diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/FunctionalityExposedForExtensions.java b/ganttzk/src/main/java/org/zkoss/ganttz/FunctionalityExposedForExtensions.java index 7b99a9054..ebd28abf8 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/FunctionalityExposedForExtensions.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/FunctionalityExposedForExtensions.java @@ -21,12 +21,14 @@ package org.zkoss.ganttz; import java.util.ArrayList; +import java.util.Calendar; import java.util.Collection; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; +import org.joda.time.LocalDate; import org.zkoss.ganttz.adapters.DomainDependency; import org.zkoss.ganttz.adapters.IAdapterToTaskFundamentalProperties; import org.zkoss.ganttz.adapters.IDomainAndBeansMapper; @@ -176,9 +178,15 @@ public class FunctionalityExposedForExtensions implements IContext { final IDetailItemModificator secondLevelModificators = configuration .getSecondLevelModificators(); - this.timeTracker = new TimeTracker(new Interval(TimeTrackerState - .year(2009), TimeTrackerState.year(2011)), planner - .getZoomLevel(), firstLevelModificators, + Calendar calendarRightNow = Calendar.getInstance(); + LocalDate localDateRightNow = LocalDate.fromCalendarFields(calendarRightNow); + LocalDate initDate = localDateRightNow.minusYears(1); + LocalDate endDate = localDateRightNow.plusYears(5); + + this.timeTracker = new TimeTracker(new Interval( + TimeTrackerState.year(initDate.getYear()), + TimeTrackerState.year(endDate.getYear())), + planner.getZoomLevel(), firstLevelModificators, secondLevelModificators, planner); } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTracker.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTracker.java index 0edfd6b6f..1547d5c48 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTracker.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTracker.java @@ -66,6 +66,8 @@ public class TimeTracker { private final Component componentOnWhichGiveFeedback; + private boolean registeredFirstTask = false; + public TimeTracker(Interval interval, Component componentOnWhichGiveFeedback) { this(interval, SeveralModificators.empty(), SeveralModificators.empty(), componentOnWhichGiveFeedback); @@ -216,21 +218,31 @@ public class TimeTracker { } private void updateIntervalIfNeeded(Task task) { - Date newStart = interval.getStart(); - Date newFinish = interval.getFinish(); - boolean changed = false; - if (interval.getStart().compareTo(startMinusOneYear(task)) > 0) { - newStart = startMinusOneYear(task); - changed = true; - } - if (interval.getFinish() - .compareTo(endPlusOneYear(task)) < 0) { - newFinish = endPlusOneYear(task); - changed = true; - } - if (changed) { - interval = new Interval(newStart, newFinish); + if (registeredFirstTask == false) { + registeredFirstTask = true; + interval = new Interval(startMinusTwoWeeks(task), + endPlusOneMonth(task)); invalidatingChangeHappened(); + } else { + Date newStart = interval.getStart(); + Date newFinish = interval.getFinish(); + + boolean changed = false; + if (interval.getStart().compareTo(startMinusTwoWeeks(task)) > 0) { + newStart = startMinusTwoWeeks(task); + changed = true; + } + + if (interval.getFinish() + .compareTo(endPlusOneMonth(task)) < 0) { + newFinish = endPlusOneMonth(task); + changed = true; + } + + if (changed) { + interval = new Interval(newStart, newFinish); + invalidatingChangeHappened(); + } } } @@ -243,4 +255,11 @@ public class TimeTracker { .toDateMidnight().toDate(); } + private Date endPlusOneMonth(Task task) { + return new LocalDate(task.getEndDate()).plusMonths(1).toDateMidnight().toDate(); + } + + private Date startMinusTwoWeeks(Task task) { + return new LocalDate(task.getBeginDate()).minusWeeks(2).toDateMidnight().toDate(); + } } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailFiveTimeTrackerState.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailFiveTimeTrackerState.java index 4a938b020..573bbe989 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailFiveTimeTrackerState.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailFiveTimeTrackerState.java @@ -28,6 +28,7 @@ import org.joda.time.DateTime; import org.joda.time.Days; import org.joda.time.LocalDate; import org.joda.time.ReadablePeriod; +import org.joda.time.Weeks; import org.zkoss.ganttz.util.Interval; /** @@ -38,6 +39,7 @@ import org.zkoss.ganttz.util.Interval; public class DetailFiveTimeTrackerState extends TimeTrackerStateUsingJodaTime { + private static final int NUMBER_OF_DAYS_MINIMUM = 50; public static final int FIRST_LEVEL_SIZE = 140; public static final int SECOND_LEVEL_SIZE = 20; @@ -118,4 +120,27 @@ public class DetailFiveTimeTrackerState extends TimeTrackerStateUsingJodaTime { return result; } + @Override + protected Interval calculateIntervalWithMinimum(Interval candidateInterval) { + Interval resultInterval; + LocalDate startDate = LocalDate.fromDateFields(candidateInterval.getStart()); + LocalDate endDate = LocalDate.fromDateFields(candidateInterval.getFinish()); + Days numberOfDays = Days.daysBetween(startDate.toDateTimeAtCurrentTime(), + endDate.toDateTimeAtCurrentTime()); + + if (numberOfDays.getDays() < this.NUMBER_OF_DAYS_MINIMUM) { + LocalDate endIntervalDate = LocalDate.fromDateFields(candidateInterval. + getStart()). + toDateMidnight(). + plusWeeks(this.NUMBER_OF_DAYS_MINIMUM).toLocalDate(); + LocalDate roundedEndIntervalDate = roundToNextYear(endIntervalDate); + resultInterval = new Interval(candidateInterval.getStart(), + roundedEndIntervalDate.toDateMidnight().toDate()); + } else { + resultInterval = candidateInterval; + } + + return resultInterval; + } + } \ No newline at end of file diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailFourTimeTrackerState.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailFourTimeTrackerState.java index 2b804fd6b..c63727a9e 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailFourTimeTrackerState.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailFourTimeTrackerState.java @@ -20,11 +20,13 @@ package org.zkoss.ganttz.timetracker.zoom; +import org.jfree.data.time.Month; import org.joda.time.DateTime; import org.joda.time.LocalDate; import org.joda.time.Months; import org.joda.time.ReadablePeriod; import org.joda.time.Weeks; +import org.zkoss.ganttz.util.Interval; /** * Zoom level for months and years and weeks in the second level @@ -33,6 +35,8 @@ import org.joda.time.Weeks; */ public class DetailFourTimeTrackerState extends TimeTrackerStateUsingJodaTime { + private static final int NUMBER_OF_WEEKS_MINIMUM = 40; + DetailFourTimeTrackerState(IDetailItemModificator firstLevelModificator, IDetailItemModificator secondLevelModificator) { super(firstLevelModificator, secondLevelModificator); @@ -89,4 +93,29 @@ public class DetailFourTimeTrackerState extends TimeTrackerStateUsingJodaTime { return down ? date.withDayOfMonth(1) : date.plusMonths(1) .withDayOfMonth(1); } + + @Override + protected Interval calculateIntervalWithMinimum(Interval candidateInterval) { + Interval resultInterval; + LocalDate startDate = LocalDate.fromDateFields(candidateInterval.getStart()); + LocalDate endDate = LocalDate.fromDateFields(candidateInterval.getFinish()); + Weeks numberOfWeeks = Weeks.weeksBetween(startDate.toDateTimeAtCurrentTime(), + endDate.toDateTimeAtCurrentTime()); + + if (numberOfWeeks.getWeeks() < this.NUMBER_OF_WEEKS_MINIMUM) { + LocalDate endIntervalDate = LocalDate.fromDateFields(candidateInterval. + getStart()). + toDateMidnight(). + plusWeeks(this.NUMBER_OF_WEEKS_MINIMUM).toLocalDate(); + LocalDate roundedEndIntervalDate = roundToNextYear(endIntervalDate); + + resultInterval = new Interval(candidateInterval.getStart(), + roundedEndIntervalDate.toDateMidnight().toDate()); + } else { + resultInterval = candidateInterval; + } + + return resultInterval; + } + } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailThreeTimeTrackerState.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailThreeTimeTrackerState.java index 4e514b354..f3f38db11 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailThreeTimeTrackerState.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailThreeTimeTrackerState.java @@ -20,10 +20,13 @@ package org.zkoss.ganttz.timetracker.zoom; +import java.util.Date; + import org.joda.time.DateTime; import org.joda.time.LocalDate; import org.joda.time.Months; import org.joda.time.ReadablePeriod; +import org.zkoss.ganttz.util.Interval; import org.zkoss.util.Locales; /** @@ -33,6 +36,8 @@ import org.zkoss.util.Locales; */ public class DetailThreeTimeTrackerState extends TimeTrackerStateUsingJodaTime { + private static final int NUMBER_OF_MONTHS_MINIMUM = 20; + DetailThreeTimeTrackerState(IDetailItemModificator firstLevelModificator, IDetailItemModificator secondLevelModificator) { super(firstLevelModificator, secondLevelModificator); @@ -104,4 +109,28 @@ public class DetailThreeTimeTrackerState extends TimeTrackerStateUsingJodaTime { } }; } + + @Override + protected Interval calculateIntervalWithMinimum(Interval candidateInterval) { + Interval resultInterval; + LocalDate startDate = LocalDate.fromDateFields(candidateInterval.getStart()); + LocalDate endDate = LocalDate.fromDateFields(candidateInterval.getFinish()); + Months numberOfMonths = + Months.monthsBetween(startDate.toDateTimeAtCurrentTime(), + endDate.toDateTimeAtCurrentTime()); + + if (numberOfMonths.getMonths() < this.NUMBER_OF_MONTHS_MINIMUM) { + LocalDate endIntervalDate = LocalDate.fromDateFields(candidateInterval. + getStart()). + toDateMidnight(). + plusMonths(this.NUMBER_OF_MONTHS_MINIMUM).toLocalDate(); + LocalDate roundedEndIntervalDate = roundToNextYear(endIntervalDate); + resultInterval = new Interval(candidateInterval.getStart(), + roundedEndIntervalDate.toDateMidnight().toDate()); + } else { + resultInterval = candidateInterval; + } + + return resultInterval; + } } \ No newline at end of file diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/TimeTrackerStateUsingJodaTime.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/TimeTrackerStateUsingJodaTime.java index 1a2d58536..7892aba5c 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/TimeTrackerStateUsingJodaTime.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/TimeTrackerStateUsingJodaTime.java @@ -25,6 +25,7 @@ import java.util.Collection; import java.util.Date; import java.util.List; +import org.jfree.data.time.Month; import org.joda.time.DateTime; import org.joda.time.LocalDate; import org.joda.time.ReadablePeriod; @@ -87,11 +88,23 @@ public abstract class TimeTrackerStateUsingJodaTime extends TimeTrackerState { protected abstract LocalDate round(LocalDate date, boolean down); + protected abstract Interval calculateIntervalWithMinimum(Interval candidateInterval); + @Override public Interval getRealIntervalFor(Interval testInterval) { LocalDate start = round(asLocalDate(testInterval.getStart()), true); - LocalDate finish = round(asLocalDate(testInterval.getFinish()), false); - return new Interval(start.toDateTimeAtStartOfDay().toDate(), finish + LocalDate finish = roundToNextYear(asLocalDate(testInterval.getFinish())); + + Interval candidateInterval = new Interval(start.toDateTimeAtStartOfDay().toDate(), finish .toDateTimeAtStartOfDay().toDate()); + + Interval resultInterval = calculateIntervalWithMinimum(candidateInterval); + return resultInterval; + } + + protected LocalDate roundToNextYear(LocalDate date) { + LocalDate dateNextYear = date.withYear(date.getYear()+1). + withMonthOfYear(Month.JANUARY).withDayOfMonth(1); + return dateNextYear; } }