branch feature/sync updated (8edf5d3 -> d63c6c1)
This is an automated email from the git hooks/post-receive script. New change to branch feature/sync in repository jtimer. See https://gitlab.nuiton.org/chorem/jtimer.git from 8edf5d3 Display of a task after edition of url in prettified json format methods to jsonify and then prettify a task (small typo edit) new 1f186b5 "use of simpler json format, sends update request to url when url is changed with the json of the task." new d63c6c1 Deletion of TaskJsonDisplayer class that was used to test the display of the json Adding an update option to the UI and an update frame (TimeTaskUpdaterView) to display the data to be sent (not finished) based on the Report UI The 2 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "adds" were already present in the repository and have only been added to this reference. Detailed log of new commits: commit d63c6c11ac5a541683cf2b39e975939efdedba8b Author: servantie <servantie.c@gmail.com> Date: Tue May 17 14:27:32 2016 +0200 Deletion of TaskJsonDisplayer class that was used to test the display of the json Adding an update option to the UI and an update frame (TimeTaskUpdaterView) to display the data to be sent (not finished) based on the Report UI commit 1f186b5720811363e3162993869f5250673d616d Author: servantie <servantie.c@gmail.com> Date: Tue May 10 11:30:43 2016 +0200 "use of simpler json format, sends update request to url when url is changed with the json of the task." Summary of changes: src/main/java/org/chorem/jtimer/JTimer.java | 18 +- .../chorem/jtimer/entities/TimerTaskHelper.java | 163 +++----- .../chorem/jtimer/io/GTimerIncrementalSaver.java | 3 +- .../org/chorem/jtimer/ui/TaskJsonDisplayer.java | 61 --- .../java/org/chorem/jtimer/ui/TimerTaskEditor.java | 3 - .../jtimer/ui/report/TimerTaskUpdaterView.java | 411 +++++++++++++++++++++ .../org/chorem/jtimer/resources/JTimer.properties | 4 + .../chorem/jtimer/resources/JTimer_fr.properties | 6 +- .../resources/TimerTaskUpdaterView.properties | 50 +++ .../resources/TimerTaskUpdaterView_fr.properties | 62 ++++ 10 files changed, 608 insertions(+), 173 deletions(-) delete mode 100644 src/main/java/org/chorem/jtimer/ui/TaskJsonDisplayer.java create mode 100644 src/main/java/org/chorem/jtimer/ui/report/TimerTaskUpdaterView.java create mode 100644 src/main/resources/org/chorem/jtimer/ui/report/resources/TimerTaskUpdaterView.properties create mode 100644 src/main/resources/org/chorem/jtimer/ui/report/resources/TimerTaskUpdaterView_fr.properties -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
This is an automated email from the git hooks/post-receive script. New commit to branch feature/sync in repository jtimer. See https://gitlab.nuiton.org/chorem/jtimer.git commit 1f186b5720811363e3162993869f5250673d616d Author: servantie <servantie.c@gmail.com> Date: Tue May 10 11:30:43 2016 +0200 "use of simpler json format, sends update request to url when url is changed with the json of the task." --- .../chorem/jtimer/entities/TimerTaskHelper.java | 197 +++++++++++++++------ .../chorem/jtimer/io/GTimerIncrementalSaver.java | 2 + 2 files changed, 149 insertions(+), 50 deletions(-) diff --git a/src/main/java/org/chorem/jtimer/entities/TimerTaskHelper.java b/src/main/java/org/chorem/jtimer/entities/TimerTaskHelper.java index 2edf112..a6de757 100644 --- a/src/main/java/org/chorem/jtimer/entities/TimerTaskHelper.java +++ b/src/main/java/org/chorem/jtimer/entities/TimerTaskHelper.java @@ -22,7 +22,16 @@ package org.chorem.jtimer.entities; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLEncoder; +import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.ZoneId; import java.util.*; /** @@ -323,13 +332,13 @@ public class TimerTaskHelper { return components; } - /** - * Returns a String in JSON format (cf schema) + /* /** + * Returns a String in JSON format (cf schema (v1)) * with all the times and annotations of one task (and * its subtasks) * @param task the task to make a JSON from * @return subtaskString the String representing the task - */ + *//* public static String tasktoJSONFormat(TimerTask task) { String taskNumber = Integer.toString(task.getNumber()); //task time ? or all times (including subtasks) @@ -345,68 +354,115 @@ public class TimerTaskHelper { subtaskString = "[]"; } - String res = "{\"path\":\"" + pathForJSON(task) + "\",\"name\":\"" + taskNumber + + String res = "{\"id\":\"" + pathForJSON(task) + "\",\"annotations\":{" + annotationsForJSON(task) + "},\"times\":" + - timesForJSON(task) + - ",\"taskTime\":" + taskTotalTime + ",\"subTasks\":" +subtaskString + "}"; + timesForJSON(task) + ",\"taskTime\":" + taskTotalTime + + "\",\"name\":\"" + taskNumber + ",\"subTasks\":" + subtaskString + "}"; return res; - } + }*/ /** - * Returns a String with the task's path - * @param task : the task - * @return path : the task's path - */ - public static String pathForJSON(TimerTask task) { - String path = ""; - TimerTask clonetask = task; - while (clonetask != null) { - path = clonetask.getName()+ "/" + path; - clonetask = clonetask.getParent(); - } - return path; - } - - /** - * Returns the annotations of the task as - * "Date" : "annotation" - * @param task : the task - * @return annotations : the task's annotations + * Returns a String in JSON format (cf schema (simplified) + * with all times and annotations of a task (without subtasks) + * @param task the task to make a JSON from + * @return result the string in JSON */ - public static String annotationsForJSON(TimerTask task) { - String annotations=""; - if (task.getAllDaysAnnotations().size() != 0) { - SortedMap<Date, String> annotationsMap = task.getAllDaysAnnotations(); - //toString pas au bon format fixme (do it manually) - for (SortedMap.Entry<Date, String> entry : annotationsMap.entrySet()) { - annotations = annotations + "\"" + entry.getKey().toString() + "\":\"" + entry.getValue() + "\","; - } - //fix for last , in the String - annotations = annotations.substring(0,annotations.length()-1); - } - return annotations; + public static String tasktoJSONFormat(TimerTask task) { + String taskID = Integer.toString(task.getNumber()); + String taskTotalTime = Long.toString(getAllTotalTime(task)); + String res = "{\"uuid\":\"" + taskID + "\",\"periods\":" + getTimesAndCommentsJSON(task) +"}"; + return res; } /** - * Returns the times of the task as - * "Date" : time - * @param task the task - * @return times : the task's times + * Returns a String with the times and comments of a task as : + * [{"id":"..","startDate":"..","duration":..,"info":".."},..] */ - public static String timesForJSON(TimerTask task) { - String times = "{"; - if (task.getAllDaysAndTimes().size() !=0) { + public static String getTimesAndCommentsJSON(TimerTask task) { + String result =""; + //todo:deal with ids (currently a silly sequence) + int sequence = 0; + if (task.getAllDaysAndTimes().size() != 0) { SortedMap<Date, Long> timesMap = task.allDaysTimes; for (SortedMap.Entry<Date, Long> entry : timesMap.entrySet()) { - times = times + "\"" + entry.getKey().toString() + "\":\"" + entry.getValue() + "\","; + //adding id, startDate and duration + //converting Date to LocalDate (to ease the .toString()) + //todo:deal with timezones + LocalDate date = entry.getKey().toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); + + result = result + "{\"id\":"+ sequence + "\",\"startDate\":\"" + date.toString() + "T00:00:00" + + "\",\"duration\":\"" + Long.toString(entry.getValue()) + ",\"info\":\""; + //adding comments (if there are any) + if (getAnnotation(task, entry.getKey()).size() != 0) { + for (String s : getAnnotation(task, entry.getKey())) { + result = result + s + ","; + } + } + result = result + "\"},"; + ++sequence; } - times = times.substring(0, times.length()-1); - } - times += "}"; - return times; + //deleting trailing ',' because of the loop + result = result.substring(0, result.length()-1); + } + + return result; } +// /** +// * Returns a String with the task's path +// * @param task : the task +// * @return path : the task's path +// */ +// public static String pathForJSON(TimerTask task) { +// String path = ""; +// TimerTask clonetask = task; +// while (clonetask != null) { +// path = clonetask.getName() + "/" + path; +// clonetask = clonetask.getParent(); +// } +// return path; +// } + +// /** +// * Returns the annotations of the task as +// * "Date" : "annotation" +// * @param task : the task +// * @return annotations : the task's annotations +// */ +// public static String annotationsForJSON(TimerTask task) { +// String annotations=""; +// if (task.getAllDaysAnnotations().size() != 0) { +// SortedMap<Date, String> annotationsMap = task.getAllDaysAnnotations(); +// //toString pas au bon format fixme (do it manually) +// for (SortedMap.Entry<Date, String> entry : annotationsMap.entrySet()) { +// annotations = annotations + "\"" + entry.getKey().toString() + "\":\"" + entry.getValue() + "\","; +// } +// //fix for last , in the String +// annotations = annotations.substring(0,annotations.length()-1); +// } +// return annotations; +// } +// +// /** +// * Returns the times of the task as +// * "Date" : time +// * @param task the task +// * @return times : the task's times +// */ +// public static String timesForJSON(TimerTask task) { +// String times = "["; +// if (task.getAllDaysAndTimes().size() !=0) { +// SortedMap<Date, Long> timesMap = task.allDaysTimes; +// for (SortedMap.Entry<Date, Long> entry : timesMap.entrySet()) { +// times = times + "{\"" + "\"startDate\":" + entry.getKey().toString() + "\",\"duration\":\"" + Long.toString(entry.getValue()) + "\"},"; +// } +// times = times.substring(0, times.length()-1); +// } +// times += "]"; +// return times; +// } + /** * Prettify the JSON String to make it * human readable @@ -443,4 +499,45 @@ public class TimerTaskHelper { } return prettiest; } + + /** + * Update a task completely + * @param task : the task to update + * + */ + public static void updateTask(TimerTask task) { + String syncURl = task.getSynchronisingURL(); + String charset = "UTF-8"; + String json = tasktoJSONFormat(task); + String query=""; + try { + query = String.format("json=%s", URLEncoder.encode(json, charset)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + URLConnection connection = null; + try { + connection = new URL("http://"+ syncURl).openConnection(); + } catch (IOException e) { + e.printStackTrace(); + } + connection.setDoOutput(true); + connection.setRequestProperty("Accept-Charset", charset); + connection.setRequestProperty("Content-Type", "application/json" + charset); + + try (OutputStream output = connection.getOutputStream()) { + output.write(query.getBytes(charset)); + } catch (IOException e) { + e.printStackTrace(); + } + + try { + InputStream response = connection.getInputStream(); + + } catch (IOException e) { + e.printStackTrace(); + } + + } } diff --git a/src/main/java/org/chorem/jtimer/io/GTimerIncrementalSaver.java b/src/main/java/org/chorem/jtimer/io/GTimerIncrementalSaver.java index 4408bd0..ea077d1 100644 --- a/src/main/java/org/chorem/jtimer/io/GTimerIncrementalSaver.java +++ b/src/main/java/org/chorem/jtimer/io/GTimerIncrementalSaver.java @@ -1186,6 +1186,8 @@ public class GTimerIncrementalSaver extends AbstractSaver implements Saver, synchronisationTaskFile.delete(); } + + TimerTaskHelper.updateTask(task); } /** -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
This is an automated email from the git hooks/post-receive script. New commit to branch feature/sync in repository jtimer. See https://gitlab.nuiton.org/chorem/jtimer.git commit d63c6c11ac5a541683cf2b39e975939efdedba8b Author: servantie <servantie.c@gmail.com> Date: Tue May 17 14:27:32 2016 +0200 Deletion of TaskJsonDisplayer class that was used to test the display of the json Adding an update option to the UI and an update frame (TimeTaskUpdaterView) to display the data to be sent (not finished) based on the Report UI --- src/main/java/org/chorem/jtimer/JTimer.java | 18 +- .../chorem/jtimer/entities/TimerTaskHelper.java | 200 ++-------- .../chorem/jtimer/io/GTimerIncrementalSaver.java | 5 +- .../org/chorem/jtimer/ui/TaskJsonDisplayer.java | 61 --- .../java/org/chorem/jtimer/ui/TimerTaskEditor.java | 3 - .../jtimer/ui/report/TimerTaskUpdaterView.java | 411 +++++++++++++++++++++ .../org/chorem/jtimer/resources/JTimer.properties | 4 + .../chorem/jtimer/resources/JTimer_fr.properties | 6 +- .../resources/TimerTaskUpdaterView.properties | 50 +++ .../resources/TimerTaskUpdaterView_fr.properties | 62 ++++ 10 files changed, 578 insertions(+), 242 deletions(-) diff --git a/src/main/java/org/chorem/jtimer/JTimer.java b/src/main/java/org/chorem/jtimer/JTimer.java index 4c488b3..c6c5089 100644 --- a/src/main/java/org/chorem/jtimer/JTimer.java +++ b/src/main/java/org/chorem/jtimer/JTimer.java @@ -69,6 +69,7 @@ import org.chorem.jtimer.entities.TimerTask; import org.chorem.jtimer.ui.*; import org.chorem.jtimer.ui.alert.AlertEditor; import org.chorem.jtimer.ui.report.ReportView; +import org.chorem.jtimer.ui.report.TimerTaskUpdaterView; import org.chorem.jtimer.ui.systray.SystrayManager; import org.chorem.jtimer.ui.tasks.IdleDialog; import org.chorem.jtimer.ui.tasks.RefreshTreeTask; @@ -375,7 +376,7 @@ public class JTimer extends SingleFrameApplication implements "closeProject", "deleteProject", "---", "quit"}; menuBar.add(createMenu("projectMenu", projectMenuActionNames)); - String[] taskMenuActionNames = { "newTask", "editTask", "closeTask", + String[] taskMenuActionNames = { "newTask", "editTask", "updateTask", "closeTask", "deleteTask", "---", "startTask", "stopAllTasks", "---", "addAnnotation", "editAlert", "increment1Task", "increment5Task", "increment30Task", "decrement1Task", @@ -667,9 +668,18 @@ public class JTimer extends SingleFrameApplication implements TimerTaskEditor editor = new TimerTaskEditor(this, task, core); show(editor); + } + /** + * Update task. + * Enabled when a task is selected + */ + @Action(enabledProperty = "selectedSingleTask") + public void updateTask() { + TimerTask task = projectsAndTasksTable.getSelectedTasks().get(0); + + TimerTaskUpdaterView updater = new TimerTaskUpdaterView(this, core, task); + show(updater); - TaskJsonDisplayer displayJson = new TaskJsonDisplayer(this, task); - show(displayJson); } /** @@ -1487,7 +1497,7 @@ public class JTimer extends SingleFrameApplication implements if (isSelectedSingleTask()) { actionNames = new String[] { "startTask", "---", - "newTask", "editTask", "closeTask", "deleteTask", + "newTask", "editTask", "updateTask", "closeTask", "deleteTask", "---", "addAnnotation", "editAlert", "increment1Task", "increment5Task", "increment30Task", "decrement1Task", "decrement5Task", "decrement30Task", "setToZero" }; diff --git a/src/main/java/org/chorem/jtimer/entities/TimerTaskHelper.java b/src/main/java/org/chorem/jtimer/entities/TimerTaskHelper.java index a6de757..b6c05f4 100644 --- a/src/main/java/org/chorem/jtimer/entities/TimerTaskHelper.java +++ b/src/main/java/org/chorem/jtimer/entities/TimerTaskHelper.java @@ -332,63 +332,57 @@ public class TimerTaskHelper { return components; } - /* /** - * Returns a String in JSON format (cf schema (v1)) - * with all the times and annotations of one task (and - * its subtasks) + /** + * Returns a String in JSON format (cf schema (simplified) + * with all times and annotations of a task (without subtasks) * @param task the task to make a JSON from - * @return subtaskString the String representing the task - *//* - public static String tasktoJSONFormat(TimerTask task) { - String taskNumber = Integer.toString(task.getNumber()); - //task time ? or all times (including subtasks) - String taskTotalTime = Long.toString(getAllTotalTime(task)); - - String subtaskString = ""; - if (task.getSubTasks().size() != 0) { - for (TimerTask subtask : task.getSubTasks()) { - subtaskString += tasktoJSONFormat(subtask); - } - } - else { - subtaskString = "[]"; - } - - String res = "{\"id\":\"" + pathForJSON(task) + - "\",\"annotations\":{" + annotationsForJSON(task) + "},\"times\":" + - timesForJSON(task) + ",\"taskTime\":" + taskTotalTime + - "\",\"name\":\"" + taskNumber + ",\"subTasks\":" + subtaskString + "}"; + * @return result the string in JSON + */ + public static String taskToJSONFormat(TimerTask task) { + Date startDate = task.getCreationDate(); + Date endDate = new Date(); + String resultingJSON = taskToJSONFormat(task, startDate, endDate); + return resultingJSON; + } - return res; - }*/ /** * Returns a String in JSON format (cf schema (simplified) * with all times and annotations of a task (without subtasks) + * in a given period between two dates * @param task the task to make a JSON from + * @param startDate the beginning date + * @param endDate the end date * @return result the string in JSON */ - public static String tasktoJSONFormat(TimerTask task) { + public static String taskToJSONFormat(TimerTask task, Date startDate, Date endDate) { + //todo : change id with something else ? String taskID = Integer.toString(task.getNumber()); - String taskTotalTime = Long.toString(getAllTotalTime(task)); - String res = "{\"uuid\":\"" + taskID + "\",\"periods\":" + getTimesAndCommentsJSON(task) +"}"; - return res; + String resultingJSON = "{\"uuid\":\"" + task.getName()+ "\",\"periods\":" + getTimesAndCommentsJSON(task, startDate, endDate) +"}"; + return resultingJSON; } /** * Returns a String with the times and comments of a task as : * [{"id":"..","startDate":"..","duration":..,"info":".."},..] + * over a defined period from startDate to endDate + * @param task : task to make a json of + * @param startDate : beginning of period to work with + * @param endDate : end of period + * @return a string in json format */ - public static String getTimesAndCommentsJSON(TimerTask task) { - String result =""; - //todo:deal with ids (currently a silly sequence) + public static String getTimesAndCommentsJSON(TimerTask task, Date startDate, Date endDate) { + String result = ""; + SortedMap<Date, Long> dates = task.getAllDaysAndTimes().subMap(startDate, endDate); + //todo:deal with ids (currently a useless sequence) int sequence = 0; if (task.getAllDaysAndTimes().size() != 0) { + result = result + "["; SortedMap<Date, Long> timesMap = task.allDaysTimes; for (SortedMap.Entry<Date, Long> entry : timesMap.entrySet()) { //adding id, startDate and duration //converting Date to LocalDate (to ease the .toString()) - //todo:deal with timezones + //todo:deal with timezones ? LocalDate date = entry.getKey().toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); result = result + "{\"id\":"+ sequence + "\",\"startDate\":\"" + date.toString() + "T00:00:00" + @@ -404,140 +398,8 @@ public class TimerTaskHelper { } //deleting trailing ',' because of the loop result = result.substring(0, result.length()-1); - } - - return result; - } - -// /** -// * Returns a String with the task's path -// * @param task : the task -// * @return path : the task's path -// */ -// public static String pathForJSON(TimerTask task) { -// String path = ""; -// TimerTask clonetask = task; -// while (clonetask != null) { -// path = clonetask.getName() + "/" + path; -// clonetask = clonetask.getParent(); -// } -// return path; -// } - -// /** -// * Returns the annotations of the task as -// * "Date" : "annotation" -// * @param task : the task -// * @return annotations : the task's annotations -// */ -// public static String annotationsForJSON(TimerTask task) { -// String annotations=""; -// if (task.getAllDaysAnnotations().size() != 0) { -// SortedMap<Date, String> annotationsMap = task.getAllDaysAnnotations(); -// //toString pas au bon format fixme (do it manually) -// for (SortedMap.Entry<Date, String> entry : annotationsMap.entrySet()) { -// annotations = annotations + "\"" + entry.getKey().toString() + "\":\"" + entry.getValue() + "\","; -// } -// //fix for last , in the String -// annotations = annotations.substring(0,annotations.length()-1); -// } -// return annotations; -// } -// -// /** -// * Returns the times of the task as -// * "Date" : time -// * @param task the task -// * @return times : the task's times -// */ -// public static String timesForJSON(TimerTask task) { -// String times = "["; -// if (task.getAllDaysAndTimes().size() !=0) { -// SortedMap<Date, Long> timesMap = task.allDaysTimes; -// for (SortedMap.Entry<Date, Long> entry : timesMap.entrySet()) { -// times = times + "{\"" + "\"startDate\":" + entry.getKey().toString() + "\",\"duration\":\"" + Long.toString(entry.getValue()) + "\"},"; -// } -// times = times.substring(0, times.length()-1); -// } -// times += "]"; -// return times; -// } - - /** - * Prettify the JSON String to make it - * human readable - * @param jsonString : the JSON string to prettify - * @return an easier to read String - */ - public static String prettifyJSON(String jsonString) { - int indent = 0; - String prettyJson; - String prettiest = ""; - //return line after each { - prettyJson = jsonString.replace("{", "{\n\t"); - //fix { \n } (useless space} - prettyJson = prettyJson.replace("}", "\n}"); - prettyJson = prettyJson.replace("{\n\t\n}", "{}"); - // return after each , - prettyJson = prettyJson.replace(",", ",\n\t"); - //change ":" into " : " - prettyJson = prettyJson.replace("\":\"", "\" : \""); - prettyJson = prettyJson.replace("\":", "\" : "); - for (int i = 0 ; i < prettyJson.length(); ++i) { - prettiest = prettiest + prettyJson.charAt(i); - if (prettyJson.charAt(i) == '{') { - ++indent; - } - else if (prettyJson.charAt(i) == '}') { - --indent; - } - if ((indent != 0) && (prettyJson.charAt(i) == '\n')) { - for (int j = 0 ; j < indent ; ++j) { - prettiest = prettiest + "\t"; - } - } - } - return prettiest; - } - - /** - * Update a task completely - * @param task : the task to update - * - */ - public static void updateTask(TimerTask task) { - String syncURl = task.getSynchronisingURL(); - String charset = "UTF-8"; - String json = tasktoJSONFormat(task); - String query=""; - try { - query = String.format("json=%s", URLEncoder.encode(json, charset)); - } catch (UnsupportedEncodingException e) { - e.printStackTrace(); - } - - URLConnection connection = null; - try { - connection = new URL("http://"+ syncURl).openConnection(); - } catch (IOException e) { - e.printStackTrace(); + result = result + "]"; } - connection.setDoOutput(true); - connection.setRequestProperty("Accept-Charset", charset); - connection.setRequestProperty("Content-Type", "application/json" + charset); - - try (OutputStream output = connection.getOutputStream()) { - output.write(query.getBytes(charset)); - } catch (IOException e) { - e.printStackTrace(); - } - - try { - InputStream response = connection.getInputStream(); - - } catch (IOException e) { - e.printStackTrace(); - } - + return result; } } diff --git a/src/main/java/org/chorem/jtimer/io/GTimerIncrementalSaver.java b/src/main/java/org/chorem/jtimer/io/GTimerIncrementalSaver.java index ea077d1..faa0f5d 100644 --- a/src/main/java/org/chorem/jtimer/io/GTimerIncrementalSaver.java +++ b/src/main/java/org/chorem/jtimer/io/GTimerIncrementalSaver.java @@ -1161,7 +1161,7 @@ public class GTimerIncrementalSaver extends AbstractSaver implements Saver, out.write("Format: " + GTIMER_FILE_VERSION + "\n"); //save URL - if(task.getSynchronisingURL() != "" || task.getSynchronisingURL() == null) { + if(!(task.getSynchronisingURL().equals("")) || task.getSynchronisingURL() !=null) { String saveURL = task.getSynchronisingURL(); out.write("SyncURL: " + saveURL + "\n"); } @@ -1185,9 +1185,6 @@ public class GTimerIncrementalSaver extends AbstractSaver implements Saver, } else { synchronisationTaskFile.delete(); } - - - TimerTaskHelper.updateTask(task); } /** diff --git a/src/main/java/org/chorem/jtimer/ui/TaskJsonDisplayer.java b/src/main/java/org/chorem/jtimer/ui/TaskJsonDisplayer.java deleted file mode 100644 index c97de1c..0000000 --- a/src/main/java/org/chorem/jtimer/ui/TaskJsonDisplayer.java +++ /dev/null @@ -1,61 +0,0 @@ -package org.chorem.jtimer.ui; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.chorem.jtimer.JTimer; -import org.chorem.jtimer.entities.TimerTask; -import org.chorem.jtimer.entities.TimerTaskHelper; -import org.chorem.jtimer.ui.widget.DialogView; - -import javax.swing.*; -import java.awt.*; - -/** - * Dummy class to display the json made from a task - * Created by servantie on 29/04/16. - */ -public class TaskJsonDisplayer extends DialogView { - /** log */ - private static Log log = LogFactory.getLog(TaskJsonDisplayer.class); - - protected JTimer parent; - - //task to display - protected TimerTask task; - - - /** - * Constructor, building the frame with one task displayed in json (prettified) - * @param parent - * @param task - */ - public TaskJsonDisplayer(JTimer parent, TimerTask task) { - super(parent.getMainFrame(), parent); - this.parent = parent; - this.task = task; - - buildUi(); - - } - - /** - * building the frame - */ - public void buildUi() { - JPanel panel = new JPanel(); - panel.add(createDisplayPanel()); - setComponent(panel); - } - - /** - * Displaying the text - */ - public JPanel createDisplayPanel() { - JPanel panel = new JPanel(); - JTextArea displayArea = new JTextArea(TimerTaskHelper.prettifyJSON(TimerTaskHelper.tasktoJSONFormat(this.task))); - panel.add(displayArea); - - return panel; - - } -} diff --git a/src/main/java/org/chorem/jtimer/ui/TimerTaskEditor.java b/src/main/java/org/chorem/jtimer/ui/TimerTaskEditor.java index 8552e63..b29b120 100644 --- a/src/main/java/org/chorem/jtimer/ui/TimerTaskEditor.java +++ b/src/main/java/org/chorem/jtimer/ui/TimerTaskEditor.java @@ -26,7 +26,6 @@ import java.awt.BorderLayout; import java.awt.Color; import java.awt.FlowLayout; import java.awt.GridLayout; -import java.net.URL; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; @@ -49,7 +48,6 @@ import javax.swing.KeyStroke; import javax.swing.ScrollPaneConstants; import javax.swing.SpinnerNumberModel; import javax.swing.SpringLayout; -import javax.swing.border.Border; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.event.DocumentEvent; @@ -65,7 +63,6 @@ import org.chorem.jtimer.entities.TimerTask; import org.chorem.jtimer.entities.TimerTaskHelper; import org.chorem.jtimer.ui.widget.DialogView; import org.jdesktop.application.Action; -import org.jdesktop.application.Task; import org.jdesktop.swingx.JXMonthView; import org.jdesktop.swingx.calendar.DateSelectionModel; diff --git a/src/main/java/org/chorem/jtimer/ui/report/TimerTaskUpdaterView.java b/src/main/java/org/chorem/jtimer/ui/report/TimerTaskUpdaterView.java new file mode 100644 index 0000000..1181dc2 --- /dev/null +++ b/src/main/java/org/chorem/jtimer/ui/report/TimerTaskUpdaterView.java @@ -0,0 +1,411 @@ + +/* + * #%L + * jTimer + * %% + * Copyright (C) 2008 - 2016 CodeLutin, Chatellier Eric + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ +package org.chorem.jtimer.ui.report; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.chorem.jtimer.JTimer; +import org.chorem.jtimer.data.TimerCore; +import org.chorem.jtimer.entities.TimerTask; +import org.jdesktop.application.*; +import org.jdesktop.application.Action; +import org.jdesktop.swingx.JXDatePicker; +import org.jdesktop.swingx.JXTaskPane; +import org.jdesktop.swingx.JXTaskPaneContainer; + +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import java.awt.*; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.net.*; +import java.text.DateFormat; +import java.util.*; + +import static org.chorem.jtimer.entities.TimerTaskHelper.taskToJSONFormat; + +/** + * Updates UI + * + * Created by servantie on 13/05/16. + */ +public class TimerTaskUpdaterView extends FrameView implements DocumentListener { + + /** Class logger */ + protected static Log log = LogFactory.getLog(TimerTaskUpdaterView.class); + + /** Timer core. */ + protected TimerCore core; + + /** Include annotations on updates */ + protected JCheckBox checkIncludesAnnotations; + + /** Date pickers, from... to */ + protected JXDatePicker datePickerFrom, datePickerTo; + + /** update output view*/ + protected JTextArea updateArea; + /** update output (as json) */ + protected String updateJson; + + /** task to update */ + protected TimerTask task; + + /** can update */ + protected boolean canUpdate; + + /** + * UpdaterView constructor. + * + * @param application parent reference + * @param core core reference + */ + public TimerTaskUpdaterView(Application application, TimerCore core, TimerTask task) { + + super(application); + + // modify frame name + // otherwise, get parent frame dimension + getFrame().setName("updateFrame"); + //getFrame().setTitle("Update"); + getFrame().setTitle(getResourceMap().getString("updateTitle")); + + this.core = core; + this.task = task; + setComponent(getMainComponent()); + + } + + /** + * Get main view component. + * + * TODO use less complicated UI (no gbl) + * @return main component + */ + protected JComponent getMainComponent() { + + JPanel configComponent = new JXTaskPaneContainer(); + + // panel for options + JXTaskPane panelGeneral = new JXTaskPane(getResourceMap().getString("updateGeneral")); + panelGeneral.setLayout(new GridBagLayout()); + panelGeneral.setSpecial(true); + + // first date picker + JLabel labelFrom = new JLabel(getResourceMap().getString("updateFrom")); + panelGeneral.add(labelFrom, new GridBagConstraints(0, 0, 1, 1, 0, 0, + GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(1, 1, 1, 1), 0, 0)); + datePickerFrom = new JXDatePicker(); + datePickerFrom.getMonthView().setDayForeground(Calendar.SUNDAY, Color.RED); + datePickerFrom.setFormats(DateFormat.getDateInstance(DateFormat.FULL)); + panelGeneral.add(datePickerFrom, new GridBagConstraints(1, 0, 1, 1, 1, 0, + GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(1, 1, 1, 1), 0, 0)); + + // second date picker + JLabel labelTo = new JLabel(getResourceMap().getString("updateTo")); + panelGeneral.add(labelTo, new GridBagConstraints(0, 1, 1, 1, 0, 0, + GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(1, 1, 1, 1), 0, 0)); + datePickerTo = new JXDatePicker(); + datePickerTo.getMonthView().setDayForeground(Calendar.SUNDAY, Color.RED); + datePickerTo.setFormats(DateFormat.getDateInstance(DateFormat.FULL)); + panelGeneral.add(datePickerTo, new GridBagConstraints(1, 1, 1, 1, 0, 0, + GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(1, 1, 1, 1), 0, 0)); + + // set current week by default + currentWeek(); + + // action button to show current or previous week + JButton currentWeekButton = new JButton(); + currentWeekButton.setBorder(BorderFactory.createEmptyBorder()); + currentWeekButton.setAction(getContext().getActionMap(this).get("currentWeek")); + panelGeneral.add(currentWeekButton, new GridBagConstraints(2, 0, 1, 1, 0, 0, + GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(1, 1, 1, 1), 0, 0)); + JButton previousWeekButton = new JButton(); + previousWeekButton.setBorder(BorderFactory.createEmptyBorder()); + previousWeekButton.setAction(getContext().getActionMap(this).get("previousWeek")); + panelGeneral.add(previousWeekButton, new GridBagConstraints(2, 1, 1, 1, 0, 0, + GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(1, 1, 1, 1), 0, 0)); + + // Option for period grouping + JPanel typePanel = new JPanel(new GridLayout(0, 2)); + panelGeneral.add(typePanel, new GridBagConstraints(0, 2, 3, 1, 0, 0, + GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); + + // miscellaneous + JXTaskPane panelOption = new JXTaskPane(getResourceMap().getString("updateOptions")); + + checkIncludesAnnotations = new JCheckBox(); + checkIncludesAnnotations.setAction(getContext().getActionMap(this).get("updateAnnotations")); + panelOption.add(checkIncludesAnnotations); + + configComponent.add(panelGeneral); + configComponent.add(panelOption); + + // panel for update output text + JPanel panelUpdate = new JPanel(new GridBagLayout()); + + updateArea = new JTextArea(); + updateArea.setFont(new Font("Courier", Font.PLAIN, 12)); + updateArea.getDocument().addDocumentListener(this); + JScrollPane jspupdate = new JScrollPane(updateArea); + panelUpdate.add(jspupdate, new GridBagConstraints(0, 0, 3, 1, 1, 1, + GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(1, 1, 1, 1), 0, 0)); + + // buttons + JButton generateButton = new JButton(); + generateButton.setAction(getContext().getActionMap(this).get("generateUpdate")); + panelUpdate.add(generateButton, new GridBagConstraints(0, 1, 1, 1, 1, 0, + GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(1, 1, 1, 1), 0, 0)); + + JButton sendUpdateButton = new JButton(); + sendUpdateButton.setAction(getContext().getActionMap(this).get("sendUpdate")); + panelUpdate.add(sendUpdateButton, new GridBagConstraints(1, 1, 1, 1, 1, 0, + GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(1, 1, 1, 1), 0, 0)); + + JButton closeButton = new JButton(); + closeButton.setAction(getContext().getActionMap(this).get("closeView")); + panelUpdate.add(closeButton, new GridBagConstraints(2, 1, 1, 1, 1, 0, + GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(1, 1, 1, 1), 0, 0)); + + // color fix on linux ? + configComponent.setBackground(panelUpdate.getBackground()); + // set minimum size to prevent "packed size" (too big) + configComponent.setMinimumSize(new Dimension(200, 0)); + + JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, configComponent, panelUpdate); + splitPane.setOneTouchExpandable(true); + return splitPane; + } + + /** + * Select current week in date pickers. + */ + @org.jdesktop.application.Action + public void currentWeek() { + fillPickerDates(0); + } + + /** + * Display previous week in date pickers. + */ + @org.jdesktop.application.Action + public void previousWeek() { + fillPickerDates(-1); + } + + /** + * Fill picker date with predefined week selection (from current) + * and apply a delay (-1 = previous week). + * + * @param delay delay to add to current week + */ + protected void fillPickerDates(int delay) { + // init dates + Calendar calendarBegin = Calendar.getInstance(); + int firstDayOfWeek = JTimer.config.getReportFirstDayOfWeek(); + if (firstDayOfWeek <= 0 || firstDayOfWeek > 7) { + firstDayOfWeek = calendarBegin.getFirstDayOfWeek(); + } + calendarBegin.set(Calendar.DAY_OF_WEEK, firstDayOfWeek); + calendarBegin.set(Calendar.HOUR, 0); + calendarBegin.set(Calendar.MINUTE, 0); + calendarBegin.set(Calendar.SECOND, 0); + calendarBegin.set(Calendar.MILLISECOND, 0); + + // calendar must be in current week by default + if (calendarBegin.getTime().after(new Date())) { + calendarBegin.add(Calendar.WEEK_OF_YEAR, -1); + } + + // get end of week + // take calendarBegin and add a week time + Calendar calendarEnd = (Calendar) calendarBegin.clone(); + calendarEnd.add(Calendar.WEEK_OF_YEAR, 1); + calendarEnd.add(Calendar.DAY_OF_YEAR, -1); // take the day before + + // apply delai + calendarBegin.add(Calendar.WEEK_OF_YEAR, delay); + calendarEnd.add(Calendar.WEEK_OF_YEAR, delay); + + datePickerFrom.setDate(calendarBegin.getTime()); + datePickerTo.setDate(calendarEnd.getTime()); + } + + /** + * Prettify the JSON String to make it + * human readable + * @param jsonString : the JSON string to prettify + * @return an easier to read String + */ + public static String prettifyJSON(String jsonString) { + int indent = 0; + String prettyJson; + String prettiest = ""; + //return line after each { + prettyJson = jsonString.replace("{", "{\n\t"); + prettyJson = prettyJson.replace("}", "\n}"); + //fix { \n } (useless space} + prettyJson = prettyJson.replace("{\n\t\n}", "{}"); + // return after each , + prettyJson = prettyJson.replace(",", ",\n\t"); + //change ":" into " : " + prettyJson = prettyJson.replace("\":\"", "\" : \""); + prettyJson = prettyJson.replace("\":", "\" : "); + for (int i = 0 ; i < prettyJson.length(); ++i) { + prettiest = prettiest + prettyJson.charAt(i); + if ((indent != 0) && (prettyJson.charAt(i) == '\n')) { + for (int j = 0 ; j < indent ; ++j) { + prettiest = prettiest + "\t"; + } + } + if (prettyJson.charAt(i) == '{') { + ++indent; + } + else if (prettyJson.charAt(i) == '}') { + --indent; + } + } + return prettiest; + } + + /** + * Close action. + */ + @org.jdesktop.application.Action + public void closeView() { + getApplication().hide(this); + } + + + /** + * Make update. + * + * Set content in {@link #updateArea} text area. + */ + @org.jdesktop.application.Action + public void generateUpdate() { + updateJson = ""; + // make String of information + updateJson = taskToJSONFormat(task, datePickerFrom.getDate(), + datePickerTo.getDate()); + + if (updateJson != null && !updateJson.isEmpty()) { + updateArea.setText(prettifyJSON(updateJson)); + } else { + updateArea.setText(""); + } + } + + + /** + * Can update ? + * + * @return true if can update + */ + public boolean isUpdatingEnabled() { + return canUpdate; + } + + /** + * Change can update property. + * + * @param enabled can update + */ + public void setUpdatingEnabled(boolean enabled) { + boolean oldValue = canUpdate; + canUpdate = enabled; + firePropertyChange("updatingEnabled", oldValue, canUpdate); + } + + /** + * send update + */ + @Action(enabledProperty = "updatingEnabled") + public void sendUpdate() { + String syncURl = task.getSynchronisingURL(); + String charset = "UTF-8"; + String query=""; + try { + query = String.format("json=%s", URLEncoder.encode(updateJson, charset)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + try { + query = String.format("json=%s", URLEncoder.encode(updateJson, charset)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + URLConnection connection = null; + try { + connection = new URL("http://"+ syncURl).openConnection(); + } catch (IOException e) { + e.printStackTrace(); + } + connection.setDoOutput(true); + connection.setRequestProperty("Accept-Charset", charset); + connection.setRequestProperty("Content-Type", "application/json" + charset); + + try (OutputStream output = connection.getOutputStream()) { + output.write(query.getBytes(charset)); + } catch (IOException e) { + e.printStackTrace(); + } + + try { + //todo: deal with responses ! + InputStream response = connection.getInputStream(); + + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void changedUpdate(DocumentEvent e) { + documentChanged(); + } + + @Override + public void insertUpdate(DocumentEvent e) { + documentChanged(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + documentChanged(); + } + + /** + * Document content changed. + * + * Update can send update property. + */ + protected void documentChanged() { + setUpdatingEnabled(updateArea.getText().trim().length() > 0); + } +} diff --git a/src/main/resources/org/chorem/jtimer/resources/JTimer.properties b/src/main/resources/org/chorem/jtimer/resources/JTimer.properties index e218c6a..a926505 100644 --- a/src/main/resources/org/chorem/jtimer/resources/JTimer.properties +++ b/src/main/resources/org/chorem/jtimer/resources/JTimer.properties @@ -62,6 +62,10 @@ editTask.Action.text = &Edit Task editTask.Action.accelerator = F2 editTask.Action.shortDescription = Edit task +updateTask.Action.text = &Update Task +updateTask.Action.accelerator = F5 +updateTask.Action.shortDescription = Update task + closeTask.Action.text = &Open/Close Task closeTask.Action.accelerator = control O closeTask.Action.shortDescription = Open or close task diff --git a/src/main/resources/org/chorem/jtimer/resources/JTimer_fr.properties b/src/main/resources/org/chorem/jtimer/resources/JTimer_fr.properties index d5a4e9e..eb4c7e3 100644 --- a/src/main/resources/org/chorem/jtimer/resources/JTimer_fr.properties +++ b/src/main/resources/org/chorem/jtimer/resources/JTimer_fr.properties @@ -41,6 +41,10 @@ newTask.Action.shortDescription = Cr\u00E9ation d'une nouvelle t\u00E2che editTask.Action.text = \u00C9dition de la t\u00E2ch&e editTask.Action.shortDescription = \u00C9dition de la t\u00E2che + +updateTask.Action.text = &Mettre \u00E0 jour +updateTask.Action.shortDescription = Mettre \u00E0 jour + closeTask.Action.text = &Ouvrir/Fermer la t\u00E2che closeTask.Action.shortDescription = Ouvrir ou fermer la t\u00E2che @@ -149,4 +153,4 @@ vetoable.saver.invalid.characters=Le nom contient des caract\u00E8res invalide ! # Start fail i18n startFail.title=Erreur -startFail.message=${Application.title} n'a pas r\u00E9ussi \u00E0 s'initiliser.\nV\u00E9rifiez que ${Application.title} n'est pas d\u00E9j\u00E0 lanc\u00E9. +startFail.message=${Application.title} n'a pas r\u00E9ussi \u00E0 s'initialiser.\nV\u00E9rifiez que ${Application.title} n'est pas d\u00E9j\u00E0 lanc\u00E9. diff --git a/src/main/resources/org/chorem/jtimer/ui/report/resources/TimerTaskUpdaterView.properties b/src/main/resources/org/chorem/jtimer/ui/report/resources/TimerTaskUpdaterView.properties new file mode 100644 index 0000000..6359a52 --- /dev/null +++ b/src/main/resources/org/chorem/jtimer/ui/report/resources/TimerTaskUpdaterView.properties @@ -0,0 +1,50 @@ +### +# #%L +# jTimer +# %% +# Copyright (C) 2007 - 2016 CodeLutin, Chatellier Eric +# %% +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program. If not, see +# <http://www.gnu.org/licenses/gpl-3.0.html>. +# #L% +### +updateTitle=${Application.title} - Update +updateGeneral=General +updateOptions=Options +updateFrom=From : +updateTo=To : +updateDaily=Daily +updateMonthly=Monthly +updateWeekly=Weekly +updateYearly=Yearly + +currentWeek.Action.icon = date_current.png +currentWeek.Action.shortDescription = Current week- + +previousWeek.Action.icon = date_previous.png +previousWeek.Action.shortDescription = Previous week + +updateAnnotations.Action.text = Include annotations + +generateUpdate.Action.text = &Generate +generateUpdate.Action.icon = applications-system.png +generateUpdate.Action.shortDescription = Generate update + +sendUpdate.Action.text = &Send +sendUpdate.Action.icon = mail-forward.png +sendUpdate.Action.shortDescription = Send update + +closeView.Action.text = &Close +closeView.Action.icon = dialog-close.png +closeView.Action.shortDescription = Close diff --git a/src/main/resources/org/chorem/jtimer/ui/report/resources/TimerTaskUpdaterView_fr.properties b/src/main/resources/org/chorem/jtimer/ui/report/resources/TimerTaskUpdaterView_fr.properties new file mode 100644 index 0000000..85d01e6 --- /dev/null +++ b/src/main/resources/org/chorem/jtimer/ui/report/resources/TimerTaskUpdaterView_fr.properties @@ -0,0 +1,62 @@ +### +# #%L +# jTimer +# %% +# Copyright (C) 2007 - 2016 CodeLutin, Chatellier Eric +# %% +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program. If not, see +# <http://www.gnu.org/licenses/gpl-3.0.html>. +# #L% +### +# update i18n +updateTitle=${Application.title} - Mise \u00E0 jour +updateGeneral=G\u00E9n\u00E9ral +updateOptions=Options +updateFrom=De : +updateTo=\u00C0 : +updateDaily=Par jour +updateMonthly=Par mois +updateWeekly=Par semaine +updateYearly=Par ann\u00E9e +updateByProject=Par projet + +updateIncludeTime=Afficher les temps +updateAnnotationsTime=avec l'heure +updateIntermediateTotalTime=Ajout des temps totaux interm\u00E9diaires +updateProjects=Projets +updateProjectsList=Liste des projets + +currentWeek.Action.icon = date_current.png +currentWeek.Action.shortDescription = Semaine courante- + +previousWeek.Action.icon = date_previous.png +previousWeek.Action.shortDescription = Semaine precedente + +updateAnnotations.Action.text = Inclure les annotations + + +showHiddenProjects.Action.text = Show hidden projects +showHiddenProjects.Action.shortDescription = Show hidden projects + +generateUpdate.Action.text = &G\u00E9n\u00E9rer +generateUpdate.Action.icon = applications-system.png +generateUpdate.Action.shortDescription = G\u00E9n\u00E9rer la mise \u00C0 jour + +sendUpdate.Action.text = &Envoyer +sendUpdate.Action.icon = mail-forward.png +sendUpdate.Action.shortDescription = Envoyer la mise \u00C0 jour + +closeView.Action.text = &Fermer +closeView.Action.icon = dialog-close.png +closeView.Action.shortDescription = Fermer -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
participants (1)
-
chorem.org scm