r2848 - in trunk: . src/main/java/org/chorem/jtimer src/main/java/org/chorem/jtimer/data src/main/java/org/chorem/jtimer/entities src/main/java/org/chorem/jtimer/io src/main/java/org/chorem/jtimer/ui src/main/java/org/chorem/jtimer/ui/alert src/main/java/org/chorem/jtimer/ui/report src/main/java/org/chorem/jtimer/ui/tasks src/main/java/org/chorem/jtimer/ui/treetable src/main/java/org/chorem/jtimer/ui/widget src/main/java/org/chorem/jtimer/utils src/test/java/org/chorem/jtimer/data src/test/
Author: echatellier Date: 2012-03-28 18:37:31 +0200 (Wed, 28 Mar 2012) New Revision: 2848 Url: http://chorem.org/repositories/revision/jtimer/2848 Log: Merge branche for new time tracking algorithm. closes #13: Time tacking incorrect after system resume closes #282: Daily time not counted correctly when crossing midnight closes #492: Hibernate is not managed as user idleness Modified: trunk/ trunk/src/main/java/org/chorem/jtimer/JTimer.java trunk/src/main/java/org/chorem/jtimer/data/TimerDataManager.java trunk/src/main/java/org/chorem/jtimer/entities/TimerAlert.java trunk/src/main/java/org/chorem/jtimer/entities/TimerTask.java trunk/src/main/java/org/chorem/jtimer/io/GTimerIncrementalSaver.java trunk/src/main/java/org/chorem/jtimer/ui/StatusBar.java trunk/src/main/java/org/chorem/jtimer/ui/TimerTaskEditor.java trunk/src/main/java/org/chorem/jtimer/ui/alert/AlertTableModel.java trunk/src/main/java/org/chorem/jtimer/ui/report/ReportUtils.java trunk/src/main/java/org/chorem/jtimer/ui/tasks/RunTaskJob.java trunk/src/main/java/org/chorem/jtimer/ui/treetable/ProjectsAndTasksModel.java trunk/src/main/java/org/chorem/jtimer/ui/widget/DurationEditor.java trunk/src/main/java/org/chorem/jtimer/utils/DailySortedMap.java trunk/src/test/java/org/chorem/jtimer/data/TimerDataManagerTest.java trunk/src/test/java/org/chorem/jtimer/io/GTimerIncrementalSaverTest.java Property changes on: trunk ___________________________________________________________________ Added: svn:mergeinfo + /branches/1.4.0-ttalgo:2840-2847 Modified: trunk/src/main/java/org/chorem/jtimer/JTimer.java =================================================================== --- trunk/src/main/java/org/chorem/jtimer/JTimer.java 2012-03-27 20:54:44 UTC (rev 2847) +++ trunk/src/main/java/org/chorem/jtimer/JTimer.java 2012-03-28 16:37:31 UTC (rev 2848) @@ -718,7 +718,7 @@ RunTaskJob job = null; TaskMonitor tm = getContext().getTaskMonitor(); - for (Task<Void, Long> t : tm.getTasks()) { + for (Task t : tm.getTasks()) { TimerTask localtask = ((RunTaskJob) t).getTask(); if (task.equals(localtask)) { job = (RunTaskJob) t; @@ -770,7 +770,7 @@ public void stopAllTasks() { TaskMonitor tm = getContext().getTaskMonitor(); - for (Task<Void, Long> t : tm.getTasks()) { + for (Task t : tm.getTasks()) { // task TimerTask ttask = ((RunTaskJob) t).getTask(); stopTask(ttask); @@ -937,7 +937,7 @@ */ @Action(enabledProperty = "selectedSingleTask") public void increment5Task() { - incrementTaskTime(5 * 60); + incrementTaskTime(5 * 60000); } /** @@ -945,7 +945,7 @@ */ @Action(enabledProperty = "selectedSingleTask") public void increment30Task() { - incrementTaskTime(30 * 60); + incrementTaskTime(30 * 60000); } /** @@ -953,7 +953,7 @@ */ @Action(enabledProperty = "selectedSingleTask") public void decrement1Task() { - incrementTaskTime(-60); + incrementTaskTime(-60000); } /** @@ -961,7 +961,7 @@ */ @Action(enabledProperty = "selectedSingleTask") public void decrement5Task() { - incrementTaskTime(-5 * 60); + incrementTaskTime(-5 * 60000); } /** @@ -969,7 +969,7 @@ */ @Action(enabledProperty = "selectedSingleTask") public void decrement30Task() { - incrementTaskTime(-30 * 60); + incrementTaskTime(-30 * 60000); } /** @@ -977,7 +977,7 @@ */ @Action(enabledProperty = "selectedSingleTask") public void increment1Task() { - incrementTaskTime(60); + incrementTaskTime(60000); } /** @@ -985,37 +985,29 @@ * * To decrement, set negative increment:) * - * @param increment increment in seconds + * @param increment increment in ms */ protected void incrementTaskTime(long increment) { TimerTask selectedTask = projectsAndTasksTable.getSelectedTasks() .get(0); - // check if task is running - RunTaskJob job = getJobForRunningTask(selectedTask); - if (job != null) { - // task is running - // increment is in seconds !!! - job.incrementTaskTime(increment * 1000); - } else { - // task is not running - Date now = new Date(); - long todayTime = selectedTask.getTime(now); + // task is not running + Date now = new Date(); + long todayTime = selectedTask.getTime(now); - long newTodayTime = todayTime + increment; + long newTodayTime = todayTime + increment; - try { - // check if + negative increment still positive - if (newTodayTime > 0) { - core.getData().changeTaskTime(selectedTask, now, - newTodayTime); - } else { - // force to 0 - core.getData().changeTaskTime(selectedTask, now, 0L); - } - } catch (DataViolationException e) { - displayErrorMessage(e.getExceptionKey()); + try { + // check if + negative increment still positive + if (newTodayTime > 0) { + core.getData().changeTaskTime(selectedTask, now, + newTodayTime); + } else { + // force to 0 + core.getData().changeTaskTime(selectedTask, now, 0L); } + } catch (DataViolationException e) { + displayErrorMessage(e.getExceptionKey()); } } Modified: trunk/src/main/java/org/chorem/jtimer/data/TimerDataManager.java =================================================================== --- trunk/src/main/java/org/chorem/jtimer/data/TimerDataManager.java 2012-03-27 20:54:44 UTC (rev 2847) +++ trunk/src/main/java/org/chorem/jtimer/data/TimerDataManager.java 2012-03-28 16:37:31 UTC (rev 2848) @@ -189,7 +189,7 @@ * * @param task the task to change time * @param date date to change time - * @param value new time in seconds + * @param value new time in ms */ public synchronized void changeTaskTime(TimerTask task, Date date, long value) { @@ -429,18 +429,18 @@ while (itDataEventListener.hasNext()) { itDataEventListener.next().preMergeTasks(destinationTask, otherTasks); } - + for (TimerTask otherTask : otherTasks) { mergeTwoTasks(destinationTask, otherTask); } - + // send post notification itDataEventListener = dataEventListeners.iterator(); while (itDataEventListener.hasNext()) { itDataEventListener.next().postMergeTasks(destinationTask, otherTasks); } } - + /** * Merge two task together. * @@ -454,7 +454,7 @@ } // task is modified during merge, deep clone it - + // make sub task list copy (concurrency) Collection<TimerTask> otherTaskSubTasks = new ArrayList<TimerTask>(otherTask.getSubTasks()); for (TimerTask otherTaskSubTask : otherTaskSubTasks) { @@ -467,7 +467,7 @@ sameTaskNameTask = destSubTask; } } - + // no similar task found if (sameTaskNameTask == null) { if (log.isDebugEnabled()) { @@ -488,14 +488,14 @@ // TODO possible bug here, task times may not be saved } } - + // copy otherTask times to current task for (Entry<Date, Long> times : otherTask.getAllDaysAndTimes().entrySet()) { Long currentDuration = destinationTask.getTime(times.getKey()); currentDuration += times.getValue(); destinationTask.setTime(times.getKey(), currentDuration); } - + // copy annotations for (Entry<Date, String> note : otherTask.getAllDaysAnnotations().entrySet()) { Date noteKey = note.getKey(); @@ -513,17 +513,17 @@ } destinationTask.addAnnotation(noteKey, note.getValue()); } - + // copy alerts for (TimerAlert alert : otherTask.getAlerts()) { destinationTask.addAlert(alert); } - + // finally otherTask still exist // empty, but still exist deleteTask(otherTask); } - + /** * Add annotation on task for specified calendar, and send event. * Modified: trunk/src/main/java/org/chorem/jtimer/entities/TimerAlert.java =================================================================== --- trunk/src/main/java/org/chorem/jtimer/entities/TimerAlert.java 2012-03-27 20:54:44 UTC (rev 2847) +++ trunk/src/main/java/org/chorem/jtimer/entities/TimerAlert.java 2012-03-28 16:37:31 UTC (rev 2848) @@ -52,7 +52,7 @@ /** Alert type. */ protected Type type; - /** Alert duration. (in seconds) */ + /** Alert duration. (in ms) */ protected long duration; /** @@ -66,7 +66,7 @@ * Constructor. * * @param type type - * @param duration duration + * @param duration duration (ms) */ public TimerAlert(Type type, long duration) { this(); Modified: trunk/src/main/java/org/chorem/jtimer/entities/TimerTask.java =================================================================== --- trunk/src/main/java/org/chorem/jtimer/entities/TimerTask.java 2012-03-27 20:54:44 UTC (rev 2847) +++ trunk/src/main/java/org/chorem/jtimer/entities/TimerTask.java 2012-03-28 16:37:31 UTC (rev 2848) @@ -72,7 +72,7 @@ protected TimerTask parent; /** - * Map calendar of day -> time. (ordered on keys) + * Map calendar of day -> time (ms). (ordered on keys) */ protected SortedMap<Date, Long> allDaysTimes; @@ -240,20 +240,18 @@ /** * Add time. * - * Calendar will be forced to 0h00:00.000 - * * @param date date - * @param seconds seconds + * @param time time in ms */ - public void setTime(Date date, Long seconds) { - allDaysTimes.put(date, seconds); + public void setTime(Date date, Long time) { + allDaysTimes.put(date, time); } /** * Get time at date. * * @param date date - * @return time at specified date + * @return time at specified date in ms */ public long getTime(Date date) { long result = 0; Modified: trunk/src/main/java/org/chorem/jtimer/io/GTimerIncrementalSaver.java =================================================================== --- trunk/src/main/java/org/chorem/jtimer/io/GTimerIncrementalSaver.java 2012-03-27 20:54:44 UTC (rev 2847) +++ trunk/src/main/java/org/chorem/jtimer/io/GTimerIncrementalSaver.java 2012-03-28 16:37:31 UTC (rev 2848) @@ -512,7 +512,7 @@ try { Date keyDate = GTimerTimeUtil.yyyyMMdd2Date(sKey); String timeString = (String) prop.get(sKey); - t.setTime(keyDate, Long.valueOf(timeString)); + t.setTime(keyDate, Long.valueOf(timeString) * 1000); } catch (NumberFormatException e) { if (log.isErrorEnabled()) { log.error("Can't convert " + prop.get(sKey) @@ -642,12 +642,12 @@ try { if ("reachtotaltime".equals(alertType)) { - Long duration = Long.parseLong(alertDuration); + Long duration = Long.parseLong(alertDuration) * 1000; TimerAlert alert = new TimerAlert( TimerAlert.Type.REACH_TOTAL_TIME, duration); task.addAlert(alert); } else if ("reachdailytime".equals(alertType)) { - Long duration = Long.parseLong(alertDuration); + Long duration = Long.parseLong(alertDuration) * 1000; TimerAlert alert = new TimerAlert( TimerAlert.Type.REACH_DAILY_TIME, duration); task.addAlert(alert); @@ -1004,9 +1004,9 @@ for (Entry<Date, Long> entry : task.getAllDaysAndTimes().entrySet()) { Date date = entry.getKey(); + long value = entry.getValue() / 1000; String gtimerDate = GTimerTimeUtil.date2yyyyMMdd(date); - - out.write(gtimerDate + " " + entry.getValue() + "\n"); + out.write(gtimerDate + " " + value + "\n"); } out.close(); @@ -1104,7 +1104,7 @@ for (TimerAlert alert : task.getAlerts()) { Type type = alert.getType(); - long duration = alert.getDuration(); + long duration = alert.getDuration() / 1000; switch (type) { case REACH_DAILY_TIME: Modified: trunk/src/main/java/org/chorem/jtimer/ui/StatusBar.java =================================================================== --- trunk/src/main/java/org/chorem/jtimer/ui/StatusBar.java 2012-03-27 20:54:44 UTC (rev 2847) +++ trunk/src/main/java/org/chorem/jtimer/ui/StatusBar.java 2012-03-28 16:37:31 UTC (rev 2848) @@ -118,7 +118,7 @@ } lblTime.setText(resourceMap .getString("todayTotalMessage", DurationFormatUtils - .formatDuration(duration * 1000, "HH:mm:ss"))); + .formatDuration(duration, "HH:mm:ss"))); } /* Modified: trunk/src/main/java/org/chorem/jtimer/ui/TimerTaskEditor.java =================================================================== --- trunk/src/main/java/org/chorem/jtimer/ui/TimerTaskEditor.java 2012-03-27 20:54:44 UTC (rev 2847) +++ trunk/src/main/java/org/chorem/jtimer/ui/TimerTaskEditor.java 2012-03-28 16:37:31 UTC (rev 2848) @@ -574,7 +574,7 @@ long time = cloneTask.getTime(date); Calendar cal = Calendar.getInstance(); // FIXME me, not use a calendar here ! - cal.setTimeInMillis(time * 1000 - cal.get(Calendar.ZONE_OFFSET)); + cal.setTimeInMillis(time - cal.get(Calendar.ZONE_OFFSET)); spinnerH.setValue(cal.get(Calendar.HOUR_OF_DAY)); spinnerM.setValue(cal.get(Calendar.MINUTE)); @@ -629,7 +629,7 @@ long seconds = ((Integer) spinnerH.getValue() * 60 * 60) + ((Integer) spinnerM.getValue() * 60) + ((Integer) spinnerS.getValue()); - cloneTask.setTime(getSelectedDay().getTime(), seconds); + cloneTask.setTime(getSelectedDay().getTime(), seconds * 1000); // annotation if (isAnnotationChanged) { Modified: trunk/src/main/java/org/chorem/jtimer/ui/alert/AlertTableModel.java =================================================================== --- trunk/src/main/java/org/chorem/jtimer/ui/alert/AlertTableModel.java 2012-03-27 20:54:44 UTC (rev 2847) +++ trunk/src/main/java/org/chorem/jtimer/ui/alert/AlertTableModel.java 2012-03-28 16:37:31 UTC (rev 2848) @@ -105,7 +105,7 @@ break; case 1: - result = alert.getDuration(); + result = alert.getDuration() / 1000; break; default: @@ -130,7 +130,7 @@ case 1: long duration = ((Long)value).longValue(); - alert.setDuration(duration); + alert.setDuration(duration * 1000); break; default: Modified: trunk/src/main/java/org/chorem/jtimer/ui/report/ReportUtils.java =================================================================== --- trunk/src/main/java/org/chorem/jtimer/ui/report/ReportUtils.java 2012-03-27 20:54:44 UTC (rev 2847) +++ trunk/src/main/java/org/chorem/jtimer/ui/report/ReportUtils.java 2012-03-28 16:37:31 UTC (rev 2848) @@ -402,8 +402,7 @@ * @return formated duration */ public String formatDuration(long duration) { - String result = DurationFormatUtils.formatDuration(duration * 1000, - "HH:mm:ss"); + String result = DurationFormatUtils.formatDuration(duration, "HH:mm:ss"); return result; } Modified: trunk/src/main/java/org/chorem/jtimer/ui/tasks/RunTaskJob.java =================================================================== --- trunk/src/main/java/org/chorem/jtimer/ui/tasks/RunTaskJob.java 2012-03-27 20:54:44 UTC (rev 2847) +++ trunk/src/main/java/org/chorem/jtimer/ui/tasks/RunTaskJob.java 2012-03-28 16:37:31 UTC (rev 2848) @@ -29,20 +29,21 @@ import java.util.Collection; import java.util.Date; import java.util.HashSet; -import java.util.List; +import java.util.concurrent.atomic.AtomicLong; import javax.swing.JOptionPane; import javax.swing.SwingUtilities; +import org.apache.commons.lang3.time.DateUtils; import org.apache.commons.lang3.time.DurationFormatUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.chorem.jtimer.JTimer; import org.chorem.jtimer.data.TimerDataManager; import org.chorem.jtimer.entities.TimerAlert; +import org.chorem.jtimer.entities.TimerAlert.Type; import org.chorem.jtimer.entities.TimerTask; import org.chorem.jtimer.entities.TimerTaskHelper; -import org.chorem.jtimer.entities.TimerAlert.Type; import org.chorem.jtimer.ui.system.SystemInfo; import org.chorem.jtimer.ui.system.SystemInfoFactory; import org.chorem.jtimer.ui.system.UnsupportedSystemInfoException; @@ -59,7 +60,7 @@ * Last update : $Date$ * By : $Author$ */ -public class RunTaskJob extends Task<Void, Long> { +public class RunTaskJob extends Task<Void, Void> { /** Class logger. */ private static Log log = LogFactory.getLog(RunTaskJob.class); @@ -79,19 +80,8 @@ /** Already thrown alert. */ protected Collection<TimerAlert> alreadyTrownAlerts; - /** Calendar instance when timing start. */ - protected Calendar taskStartCalendar; - - /** - * Offset to adjust time for current day. - * Include : - * - Task idle time (task was running but time not counted) - * - Manual user incremented time - */ - protected long offsetTimeInMs; - /** Last publish time to detect hibernate. */ - protected long lastPublishTimestamp; + protected AtomicLong lastUserActivity; /** Want to stop flag. */ protected Boolean bWantToStop; @@ -146,10 +136,12 @@ // check alert to be fired for (TimerAlert alert : task.getAlerts()) { if (alert.getType().equals(Type.REACH_DAILY_TIME) - && TimerTaskHelper.getTotalTime(task, now) > alert.getDuration()) { + && TimerTaskHelper.getTotalTime(task, now) > alert + .getDuration()) { alreadyTrownAlerts.add(alert.clone()); } else if (alert.getType().equals(Type.REACH_TOTAL_TIME) - && TimerTaskHelper.getAllTotalTime(task) > alert.getDuration()) { + && TimerTaskHelper.getAllTotalTime(task) > alert + .getDuration()) { alreadyTrownAlerts.add(alert.clone()); } } @@ -171,62 +163,6 @@ return managedTask; } - /** - * Method to increment time while task is running (in ms). - * - * @param increment increment, can be negative - */ - public void incrementTaskTime(long increment) { - - long nowTimestamp = Calendar.getInstance().getTimeInMillis(); - - // new var, to not modify parameter - long localIncrement = increment; - - // do go over 0 - if (nowTimestamp - taskStartCalendar.getTimeInMillis() - + offsetTimeInMs + increment < 0) { - localIncrement = -(nowTimestamp - taskStartCalendar.getTimeInMillis() - + offsetTimeInMs); - } - - offsetTimeInMs += localIncrement; - } - - /** - * Reset timing. - * - * For example if task goes over 0h00, need to reset... - */ - public void resetTiming() { - - taskStartCalendar = Calendar.getInstance(); - lastPublishTimestamp = taskStartCalendar.getTimeInMillis(); - // need to be this for hibernate in same day - offsetTimeInMs = managedTask.getTime(new Date()) * 1000; - } - - /** - * Check if task need to be reset. - * - * Test if today number if different of taskStartCalendar day number - */ - protected void checkReset() { - - Calendar nowCalendar = Calendar.getInstance(); - - // si les jours actuel et jours de debut de start ne sont - // pas identiques : reset - if (nowCalendar.get(Calendar.DAY_OF_YEAR) != taskStartCalendar - .get(Calendar.DAY_OF_YEAR)) { - if (log.isInfoEnabled()) { - log.info("Day change detected, reset timing"); - } - resetTiming(); - } - - } - /* * @see org.jdesktop.swingworker.SwingWorker#doInBackground() */ @@ -237,28 +173,27 @@ // notify ui parentApp.startedTask(managedTask); - // reset on start just for init - resetTiming(); + // init + lastUserActivity = new AtomicLong(System.currentTimeMillis()); // get idle time long configIdleTime = JTimer.config.getIdleTime() * 1000; boolean dontWantToStop = true; while (dontWantToStop) { - long currentTime = Calendar.getInstance().getTimeInMillis(); - // try to detect hibernate idle time - if (currentTime - lastPublishTimestamp >= configIdleTime) { - // hibernate detected - // update time without idle time for specified day - if (log.isInfoEnabled()) { - log.info("Hibernate detected, reseting timing"); - } - resetTiming(); - } + // this algorithm is based on this atomic operation + // that ensure hibernate won't break time tracking + long oldUserActivity = lastUserActivity.getAndSet(System.currentTimeMillis()); - lastPublishTimestamp = currentTime; + // check for idleness with last user activity (real idle and hibernate) + long delta = lastUserActivity.get() - oldUserActivity; + // time have to be published, even if idle is detected + // because time adjustment will remove more time than published + // one if done after + addTaskDelta(lastUserActivity.get(), delta); + // check user idle time long idleTime = 0; if (systemInfo != null) { // idle time available @@ -269,65 +204,36 @@ } } - // check reset before publish (day change) - checkReset(); + if (delta >= configIdleTime || idleTime >= configIdleTime) { - // if long idleTime is unavailable, if is always false - if (idleTime >= configIdleTime) { + long userIdleTime = Math.max(delta, idleTime); - // to not display negative time near midnight - long idleTimeOffset = Math.min(idleTime, currentTime - taskStartCalendar.getTimeInMillis()); + // remove delta from now + addTaskDelta(lastUserActivity.get(), -userIdleTime); - // idle detected - // update time without idle time - // math.min > for idle detected at 0:00 - offsetTimeInMs -= idleTimeOffset; - publish(currentTime - taskStartCalendar.getTimeInMillis() + offsetTimeInMs); - - // send idle detect event - JTimer parentApplication = (JTimer)getApplication(); + // display idle detected (blocking call) + JTimer parentApplication = (JTimer) getApplication(); parentApplication.preIdleDetect(); - // ask user what to do (long blocking call) - int option = IdleDialog.showIdleDialog(currentTime - idleTime); - // send idle detect event + int option = IdleDialog.showIdleDialog(lastUserActivity.get() - userIdleTime); parentApplication.postIdleDetect(); - // day can have changed during idle - checkReset(); + // restart timing from current time after idle + // mandadory call, otherwise, next iteration will display idle + // dialog again + oldUserActivity = lastUserActivity.getAndSet(System.currentTimeMillis()); + delta = lastUserActivity.get() - oldUserActivity; - // get time after user idle - long afterIdleTime = Calendar.getInstance().getTimeInMillis(); - lastPublishTimestamp = afterIdleTime; - switch (option) { - case IdleDialog.REVERT: // just stop the task ((JTimer) getApplication()).stopTask(managedTask); break; case IdleDialog.CONTINUE: - // refresh time - // remove idle time previously added - offsetTimeInMs += idleTimeOffset; - publish(afterIdleTime - taskStartCalendar.getTimeInMillis() - + offsetTimeInMs); + // readd delta since oldUserActivity + addTaskDelta(lastUserActivity.get() - userIdleTime, delta + userIdleTime); break; - - default: // RESUME - - // resume = increment idle time - offsetTimeInMs -= afterIdleTime - currentTime; - // update time - publish(afterIdleTime - taskStartCalendar.getTimeInMillis() - + offsetTimeInMs); - break; - } - } else { - // pas de idle, met a jour le temps - publish(currentTime - taskStartCalendar.getTimeInMillis() + - offsetTimeInMs); } Thread.sleep(1000); // 1s @@ -341,20 +247,52 @@ return null; } - /* - * @see application.Task#process(java.util.List) + /** + * Add task delta. + * + * @param oldUserActivity time when delta was notified + * @param delta delta to add */ - @Override - protected void process(List<Long> durations) { + protected void addTaskDelta(long from, long delta) { - // take last notification - // can be notified of many result - // for example, if UI lag... - long currentDuration = durations.get(durations.size() - 1); + long localDelta = delta; - dataManager.changeTaskTime(managedTask, new Date(), - currentDuration / 1000); + if (log.isDebugEnabled()) { + log.debug("Adding delta to task : " + delta); + } + // remove time + if (localDelta < 0) { + Date currentDate = new Date(from); + while (localDelta < 0) { + Date todayMidnight = DateUtils.truncate(currentDate, Calendar.DAY_OF_MONTH); + long msToMidnight = currentDate.getTime() - todayMidnight.getTime(); + long toRemove = Math.min(-localDelta, msToMidnight); + dataManager.changeTaskTime(managedTask, currentDate, managedTask.getTime(currentDate) - toRemove); + if (log.isDebugEnabled()) { + log.debug(" remove delta to task on " + currentDate + " : " + toRemove); + } + localDelta += toRemove; + currentDate = DateUtils.addMilliseconds(todayMidnight, -1); + } + } else { + // add time + Date currentDate = new Date(from); + while (localDelta > 0) { + Date today235959 = DateUtils.truncate(currentDate, Calendar.DAY_OF_MONTH); + today235959 = DateUtils.addDays(today235959, 1); + today235959 = DateUtils.addMilliseconds(today235959, -1); + long msToMidnight = today235959.getTime() - currentDate.getTime(); + long toAdd = Math.min(localDelta, msToMidnight); + dataManager.changeTaskTime(managedTask, currentDate, managedTask.getTime(currentDate) + toAdd); + if (log.isDebugEnabled()) { + log.debug(" adding delta to task on " + currentDate + " : " + toAdd); + } + localDelta -= toAdd; + currentDate = DateUtils.addMilliseconds(today235959, 1); + } + } + checkTaskAlerts(managedTask); } @@ -370,12 +308,16 @@ for (TimerAlert alert : task.getAlerts()) { if (!alreadyTrownAlerts.contains(alert)) { if (alert.getType().equals(Type.REACH_DAILY_TIME) - && TimerTaskHelper.getTotalTime(task, now) >= alert.getDuration()) { - displayAlert(task, Type.REACH_DAILY_TIME, alert.getDuration()); + && TimerTaskHelper.getTotalTime(task, now) >= alert + .getDuration()) { + displayAlert(task, Type.REACH_DAILY_TIME, + alert.getDuration()); alreadyTrownAlerts.add(alert.clone()); } else if (alert.getType().equals(Type.REACH_TOTAL_TIME) - && TimerTaskHelper.getAllTotalTime(task) >= alert.getDuration()) { - displayAlert(task, Type.REACH_TOTAL_TIME, alert.getDuration()); + && TimerTaskHelper.getAllTotalTime(task) >= alert + .getDuration()) { + displayAlert(task, Type.REACH_TOTAL_TIME, + alert.getDuration()); alreadyTrownAlerts.add(alert.clone()); } } @@ -401,13 +343,16 @@ SwingUtilities.invokeLater(new Runnable() { public void run() { String alertMessage = null; - String formattedTime = DurationFormatUtils.formatDuration(alertDuration * 1000, "HH:mm:ss"); + String formattedTime = DurationFormatUtils.formatDuration( + alertDuration, "HH:mm:ss"); if (Type.REACH_DAILY_TIME.equals(alertType)) { alertMessage = getResourceMap().getString( - "alert.dailyAlertMessage", task.getName(), formattedTime); + "alert.dailyAlertMessage", task.getName(), + formattedTime); } else if (Type.REACH_TOTAL_TIME.equals(alertType)) { alertMessage = getResourceMap().getString( - "alert.totalAlertMessage", task.getName(), formattedTime); + "alert.totalAlertMessage", task.getName(), + formattedTime); } JOptionPane.showMessageDialog(null, alertMessage, Modified: trunk/src/main/java/org/chorem/jtimer/ui/treetable/ProjectsAndTasksModel.java =================================================================== --- trunk/src/main/java/org/chorem/jtimer/ui/treetable/ProjectsAndTasksModel.java 2012-03-27 20:54:44 UTC (rev 2847) +++ trunk/src/main/java/org/chorem/jtimer/ui/treetable/ProjectsAndTasksModel.java 2012-03-28 16:37:31 UTC (rev 2848) @@ -155,11 +155,11 @@ break; case 1: value = DurationFormatUtils.formatDuration(TimerTaskHelper - .getTotalTime(task, new Date()) * 1000, "HH:mm:ss"); + .getTotalTime(task, new Date()), "HH:mm:ss"); break; case 2: value = DurationFormatUtils.formatDuration(TimerTaskHelper - .getAllTotalTime(task) * 1000, "HH:mm:ss"); + .getAllTotalTime(task), "HH:mm:ss"); break; } } else { Modified: trunk/src/main/java/org/chorem/jtimer/ui/widget/DurationEditor.java =================================================================== --- trunk/src/main/java/org/chorem/jtimer/ui/widget/DurationEditor.java 2012-03-27 20:54:44 UTC (rev 2847) +++ trunk/src/main/java/org/chorem/jtimer/ui/widget/DurationEditor.java 2012-03-28 16:37:31 UTC (rev 2848) @@ -68,7 +68,7 @@ /** Second spinner model. */ protected SpinnerNumberModel secondSpinnerModel; - /** Duration. */ + /** Duration (in ms). */ protected long duration; /** Property changes on: trunk/src/main/java/org/chorem/jtimer/utils/DailySortedMap.java ___________________________________________________________________ Deleted: svn:mergeinfo - Modified: trunk/src/test/java/org/chorem/jtimer/data/TimerDataManagerTest.java =================================================================== --- trunk/src/test/java/org/chorem/jtimer/data/TimerDataManagerTest.java 2012-03-27 20:54:44 UTC (rev 2847) +++ trunk/src/test/java/org/chorem/jtimer/data/TimerDataManagerTest.java 2012-03-28 16:37:31 UTC (rev 2848) @@ -423,8 +423,8 @@ Assert.assertEquals(task2.getSubTasks().size(), 2); Assert.assertEquals(getRecursiveAnnotationsCount(Collections.singleton(task2)), 2); Assert.assertEquals(task3.getSubTasks().size(), 4); - Assert.assertEquals(TimerTaskHelper.getAllTotalTime(task1), 55035); - Assert.assertEquals(TimerTaskHelper.getAllTotalTime(task2), 65602); + Assert.assertEquals(TimerTaskHelper.getAllTotalTime(task1), 55035000); + Assert.assertEquals(TimerTaskHelper.getAllTotalTime(task2), 65602000); // merge tasks dataManager.mergeTasks(task1, Collections.singletonList(task2)); @@ -445,7 +445,7 @@ Assert.assertEquals(task1a.getSubTasks().size(), 4); Assert.assertEquals(getRecursiveAnnotationsCount(Collections.singleton(task1a)), 5 + 2); Assert.assertEquals(task3a.getSubTasks().size(), 3); - Assert.assertEquals(TimerTaskHelper.getAllTotalTime(task1a), 55035 + 65602); + Assert.assertEquals(TimerTaskHelper.getAllTotalTime(task1a), 55035000 + 65602000); } /** @@ -468,15 +468,15 @@ // add THE conflict task name TimerTask tTreeTests = new TimerTask("Tree tests"); tTreeTests.setCreationDate(new Date()); - tTreeTests.setTime(new Date(), 200l); + tTreeTests.setTime(new Date(), Long.valueOf(200000)); dataManager.addTask(task1, tTreeTests); Assert.assertEquals(task1.getSubTasks().size(), 3); - Assert.assertEquals(TimerTaskHelper.getAllTotalTime(task1), 55035 + 200); + Assert.assertEquals(TimerTaskHelper.getAllTotalTime(task1), 55035000 + 200000); TimerTask task2 = findTask(projectsBefore, "jTimer/Unit tests/UI tests"); Assert.assertEquals(task2.getSubTasks().size(), 2); - Assert.assertEquals(TimerTaskHelper.getAllTotalTime(task2), 65602); + Assert.assertEquals(TimerTaskHelper.getAllTotalTime(task2), 65602000); // merge tasks dataManager.mergeTasks(task1, Collections.singletonList(task2)); @@ -495,7 +495,7 @@ // 4 = conflict resolved Assert.assertEquals(task1a.getSubTasks().size(), 4); Assert.assertEquals(TimerTaskHelper.getAllTotalTime(task1a), - 55035 + 65602 + 200); + 55035000 + 65602000 + 200000); } /** @@ -521,9 +521,9 @@ .singleton(task1)), 0); // add new project - TimerAlert alert1 = new TimerAlert(TimerAlert.Type.REACH_DAILY_TIME, 3600); - TimerAlert alert2 = new TimerAlert(TimerAlert.Type.REACH_DAILY_TIME, 7200); - TimerAlert alert3 = new TimerAlert(TimerAlert.Type.REACH_TOTAL_TIME, 10800); + TimerAlert alert1 = new TimerAlert(TimerAlert.Type.REACH_DAILY_TIME, 3600000); + TimerAlert alert2 = new TimerAlert(TimerAlert.Type.REACH_DAILY_TIME, 7200000); + TimerAlert alert3 = new TimerAlert(TimerAlert.Type.REACH_TOTAL_TIME, 10800000); task1.addAlert(alert1); task1.addAlert(alert2); task1.addAlert(alert3); @@ -546,13 +546,13 @@ boolean alert2found = false; boolean alert3found = false; for (TimerAlert alert : task1a.getAlerts()) { - if (alert.getType().equals(Type.REACH_DAILY_TIME) && alert.getDuration() == 3600) { + if (alert.getType().equals(Type.REACH_DAILY_TIME) && alert.getDuration() == 3600000) { alert1found = true; } - if (alert.getType().equals(Type.REACH_DAILY_TIME) && alert.getDuration() == 7200) { + if (alert.getType().equals(Type.REACH_DAILY_TIME) && alert.getDuration() == 7200000) { alert2found = true; } - if (alert.getType().equals(Type.REACH_TOTAL_TIME) && alert.getDuration() == 10800) { + if (alert.getType().equals(Type.REACH_TOTAL_TIME) && alert.getDuration() == 10800000) { alert3found = true; } } Modified: trunk/src/test/java/org/chorem/jtimer/io/GTimerIncrementalSaverTest.java =================================================================== --- trunk/src/test/java/org/chorem/jtimer/io/GTimerIncrementalSaverTest.java 2012-03-27 20:54:44 UTC (rev 2847) +++ trunk/src/test/java/org/chorem/jtimer/io/GTimerIncrementalSaverTest.java 2012-03-28 16:37:31 UTC (rev 2848) @@ -195,7 +195,7 @@ for (Long time : task.getAllDaysAndTimes().values()) { totalTime += time.longValue(); } - Assert.assertEquals(11391, totalTime); + Assert.assertEquals(totalTime, 11391000); // test 20080909 9000 @@ -203,25 +203,25 @@ calendar.set(Calendar.YEAR, 2008); calendar.set(Calendar.MONTH, 8); calendar.set(Calendar.DAY_OF_MONTH, 9); - Assert.assertEquals(task.getTime(calendar.getTime()), 9000); + Assert.assertEquals(task.getTime(calendar.getTime()), 9000000); // 20080922 13 calendar.set(Calendar.YEAR, 2008); calendar.set(Calendar.MONTH, 8); calendar.set(Calendar.DAY_OF_MONTH, 22); - Assert.assertEquals(task.getTime(calendar.getTime()), 13); + Assert.assertEquals(task.getTime(calendar.getTime()), 13000); // 20080930 2332 calendar.set(Calendar.YEAR, 2008); calendar.set(Calendar.MONTH, 8); calendar.set(Calendar.DAY_OF_MONTH, 30); - Assert.assertEquals(2332, task.getTime(calendar.getTime())); + Assert.assertEquals(task.getTime(calendar.getTime()), 2332000); // 20081011 46 calendar.set(Calendar.YEAR, 2008); calendar.set(Calendar.MONTH, 9); calendar.set(Calendar.DAY_OF_MONTH, 11); - Assert.assertEquals(46, task.getTime(calendar.getTime())); + Assert.assertEquals(task.getTime(calendar.getTime()), 46000); /*FIXME saver.unlock(); } catch (DataLockingException e) { @@ -303,11 +303,11 @@ // first alert Assert.assertEquals(task.getAlerts().get(0).getType(), TimerAlert.Type.REACH_DAILY_TIME); - Assert.assertEquals(task.getAlerts().get(0).getDuration(), 3600); + Assert.assertEquals(task.getAlerts().get(0).getDuration(), 3600000); // second alert Assert.assertEquals(task.getAlerts().get(1).getType(), TimerAlert.Type.REACH_TOTAL_TIME); - Assert.assertEquals(task.getAlerts().get(1).getDuration(), 25000); + Assert.assertEquals(task.getAlerts().get(1).getDuration(), 25000000); /*FIXME saver.unlock(); } catch (DataLockingException e) { @@ -339,7 +339,7 @@ TimerTask task1 = findTask(projects, "No project/Test no parent project"); Assert.assertNotNull(task1); - Assert.assertEquals(TimerTaskHelper.getAllTotalTime(task1), 9644); + Assert.assertEquals(TimerTaskHelper.getAllTotalTime(task1), 9644000); /*FIXME testSaver.unlock(); } catch (DataLockingException e) {
participants (1)
-
echatellier@users.chorem.org