diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/FunctionalityExposedForExtensions.java b/ganttzk/src/main/java/org/zkoss/ganttz/FunctionalityExposedForExtensions.java index 0f64c3363..6f27897a0 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/FunctionalityExposedForExtensions.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/FunctionalityExposedForExtensions.java @@ -44,6 +44,7 @@ import org.zkoss.ganttz.data.TaskLeaf; import org.zkoss.ganttz.data.criticalpath.CriticalPathCalculator; import org.zkoss.ganttz.extensions.IContext; import org.zkoss.ganttz.timetracker.TimeTracker; +import org.zkoss.ganttz.timetracker.zoom.IDetailItemModificator; import org.zkoss.ganttz.timetracker.zoom.TimeTrackerState; import org.zkoss.ganttz.util.Interval; import org.zkoss.zk.ui.Component; @@ -154,13 +155,16 @@ public class FunctionalityExposedForExtensions implements IContext { public FunctionalityExposedForExtensions(Planner planner, IAdapterToTaskFundamentalProperties adapter, - IStructureNavigator navigator, GanttDiagramGraph diagramGraph) { + IStructureNavigator navigator, GanttDiagramGraph diagramGraph, + IDetailItemModificator firstLevelModificator, + IDetailItemModificator secondLevelModificator) { this.planner = planner; this.adapter = adapter; this.navigator = navigator; this.diagramGraph = diagramGraph; this.timeTracker = new TimeTracker(new Interval(TimeTrackerState - .year(2009), TimeTrackerState.year(2011))); + .year(2009), TimeTrackerState.year(2011)), + firstLevelModificator, secondLevelModificator); } /** diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/Planner.java b/ganttzk/src/main/java/org/zkoss/ganttz/Planner.java index 77ff0fc0e..48c65bc11 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/Planner.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/Planner.java @@ -179,7 +179,8 @@ public class Planner extends HtmlMacroComponent { configuration.isDependenciesConstraintsHavePriority()); FunctionalityExposedForExtensions newContext = new FunctionalityExposedForExtensions( this, configuration.getAdapter(), configuration.getNavigator(), - diagramGraph); + diagramGraph, configuration.getFirstLevelModificators(), + configuration.getSecondLevelModificators()); this.contextualizedGlobalCommands = contextualize(newContext, configuration.getGlobalCommands()); this.commandsOnTasksContextualized = contextualize(newContext, diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/adapters/PlannerConfiguration.java b/ganttzk/src/main/java/org/zkoss/ganttz/adapters/PlannerConfiguration.java index 2c6b19982..df55bcb1e 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/adapters/PlannerConfiguration.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/adapters/PlannerConfiguration.java @@ -32,6 +32,8 @@ import org.zkoss.ganttz.extensions.ICommand; import org.zkoss.ganttz.extensions.ICommandOnTask; import org.zkoss.ganttz.extensions.IContext; import org.zkoss.ganttz.extensions.IContextWithPlannerTask; +import org.zkoss.ganttz.timetracker.zoom.IDetailItemModificator; +import org.zkoss.ganttz.timetracker.zoom.SeveralModificators; import org.zkoss.zk.ui.Component; /** @@ -98,6 +100,12 @@ public class PlannerConfiguration implements IDisabilityConfiguration { private boolean criticalPathEnabled = true; + private IDetailItemModificator firstLevelModificators = SeveralModificators + .empty(); + + private IDetailItemModificator secondLevelModificators = SeveralModificators + .empty(); + public PlannerConfiguration(IAdapterToTaskFundamentalProperties adapter, IStructureNavigator navigator, List data) { this.adapter = adapter; @@ -232,4 +240,24 @@ public class PlannerConfiguration implements IDisabilityConfiguration { return criticalPathEnabled; } + public IDetailItemModificator getSecondLevelModificators() { + return secondLevelModificators; + } + + public void setSecondLevelModificators( + IDetailItemModificator... secondLevelModificators) { + this.secondLevelModificators = SeveralModificators + .create(secondLevelModificators); + } + + public IDetailItemModificator getFirstLevelModificators() { + return firstLevelModificators; + } + + public void setFirstLevelModificators( + IDetailItemModificator... firstLevelModificators) { + this.firstLevelModificators = SeveralModificators + .create(firstLevelModificators); + } + } 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 b6f5c1b67..9eaaaffa4 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTracker.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTracker.java @@ -25,12 +25,15 @@ import java.beans.PropertyChangeListener; import java.util.Collection; import java.util.Date; +import org.apache.commons.lang.Validate; import org.joda.time.LocalDate; import org.zkoss.ganttz.DatesMapperOnInterval; import org.zkoss.ganttz.IDatesMapper; import org.zkoss.ganttz.data.Task; import org.zkoss.ganttz.timetracker.zoom.DetailItem; +import org.zkoss.ganttz.timetracker.zoom.IDetailItemModificator; import org.zkoss.ganttz.timetracker.zoom.IZoomLevelChangedListener; +import org.zkoss.ganttz.timetracker.zoom.SeveralModificators; import org.zkoss.ganttz.timetracker.zoom.TimeTrackerState; import org.zkoss.ganttz.timetracker.zoom.ZoomLevel; import org.zkoss.ganttz.util.Interval; @@ -52,9 +55,23 @@ public class TimeTracker { private Interval interval; - public TimeTracker(Interval interval) { - this.interval = interval; + private final IDetailItemModificator firstLevelModificator; + private final IDetailItemModificator secondLevelModificator; + + public TimeTracker(Interval interval) { + this(interval, SeveralModificators.empty(), SeveralModificators.empty()); + } + + public TimeTracker(Interval interval, + IDetailItemModificator firstLevelModificator, + IDetailItemModificator secondLevelModificator) { + Validate.notNull(interval); + Validate.notNull(firstLevelModificator); + Validate.notNull(secondLevelModificator); + this.interval = interval; + this.firstLevelModificator = firstLevelModificator; + this.secondLevelModificator = secondLevelModificator; } public ZoomLevel getDetailLevel() { @@ -91,8 +108,9 @@ public class TimeTracker { return realIntervalCached; } - private TimeTrackerState getTimeTrackerState() { - return detailLevel.getTimeTrackerState(); + public TimeTrackerState getTimeTrackerState() { + return detailLevel.getTimeTrackerState(firstLevelModificator, + secondLevelModificator); } private void fireZoomChanged() { diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTrackerComponent.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTrackerComponent.java index d18849239..f2539ed20 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTrackerComponent.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTrackerComponent.java @@ -99,7 +99,7 @@ public abstract class TimeTrackerComponent extends HtmlMacroComponent { } private TimeTrackerState getTimeTrackerState() { - return getTimeTracker().getDetailLevel().getTimeTrackerState(); + return getTimeTracker().getTimeTrackerState(); } private Command _onincreasecmd = new ComponentCommand("onIncrease", 0) { 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 0bea2e784..4a938b020 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 @@ -37,20 +37,20 @@ import org.zkoss.ganttz.util.Interval; */ public class DetailFiveTimeTrackerState extends TimeTrackerStateUsingJodaTime { + public static final int FIRST_LEVEL_SIZE = 140; public static final int SECOND_LEVEL_SIZE = 20; - public static final DetailFiveTimeTrackerState INSTANCE = new DetailFiveTimeTrackerState(); + DetailFiveTimeTrackerState(IDetailItemModificator firstLevelModificator, + IDetailItemModificator secondLevelModificator) { + super(firstLevelModificator, secondLevelModificator); + } public final double daysPerPixel() { return ((double) 1 / SECOND_LEVEL_SIZE); } - private DetailFiveTimeTrackerState() { - - } - @Override protected IDetailItemCreator getDetailItemCreatorFirstLevel() { return new IDetailItemCreator() { 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 2390f142e..2b804fd6b 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 @@ -33,7 +33,10 @@ import org.joda.time.Weeks; */ public class DetailFourTimeTrackerState extends TimeTrackerStateUsingJodaTime { - public static final DetailFourTimeTrackerState INSTANCE = new DetailFourTimeTrackerState(); + DetailFourTimeTrackerState(IDetailItemModificator firstLevelModificator, + IDetailItemModificator secondLevelModificator) { + super(firstLevelModificator, secondLevelModificator); + } private static final int FIRST_LEVEL_SIZE = 200; private static final int SECOND_LEVEL_SIZE = 50; @@ -42,6 +45,7 @@ public class DetailFourTimeTrackerState extends TimeTrackerStateUsingJodaTime { return ((double) 7 / SECOND_LEVEL_SIZE); } + @Override protected IDetailItemCreator getDetailItemCreatorFirstLevel() { return new IDetailItemCreator() { diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailOneTimeTrackerState.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailOneTimeTrackerState.java index 6fb57df9e..c1e2e0d1a 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailOneTimeTrackerState.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailOneTimeTrackerState.java @@ -33,7 +33,6 @@ import org.zkoss.ganttz.util.Interval; */ public class DetailOneTimeTrackerState extends TimeTrackerState { - public static final DetailOneTimeTrackerState INSTANCE = new DetailOneTimeTrackerState(); private static final int FIRST_LEVEL_ITEM_SIZE = 200; private static final int SECOND_LEVEL_ITEM_SIZE = 100; @@ -41,8 +40,10 @@ public class DetailOneTimeTrackerState extends TimeTrackerState { return ((double) 365 / FIRST_LEVEL_ITEM_SIZE); } - private DetailOneTimeTrackerState() { - }; + DetailOneTimeTrackerState(IDetailItemModificator firstLevelModificator, + IDetailItemModificator secondLevelModificator) { + super(firstLevelModificator, secondLevelModificator); + } private Collection buildCollectionDetailsFirstLevel( int initialYear, int endYear) { 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 f64392259..4e514b354 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 @@ -33,7 +33,10 @@ import org.zkoss.util.Locales; */ public class DetailThreeTimeTrackerState extends TimeTrackerStateUsingJodaTime { - public static final DetailThreeTimeTrackerState INSTANCE = new DetailThreeTimeTrackerState(); + DetailThreeTimeTrackerState(IDetailItemModificator firstLevelModificator, + IDetailItemModificator secondLevelModificator) { + super(firstLevelModificator, secondLevelModificator); + } private static final int FIRST_LEVEL_SIZE = 300; protected static final int SECOND_LEVEL_SIZE = 50; @@ -42,9 +45,6 @@ public class DetailThreeTimeTrackerState extends TimeTrackerStateUsingJodaTime { return ((double) 182.5 / FIRST_LEVEL_SIZE); } - private DetailThreeTimeTrackerState() { - } - @Override protected ReadablePeriod getPeriodFirstLevel() { return Months.months(6); diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailTwoTimeTrackerState.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailTwoTimeTrackerState.java index 0777f024a..fe274cc2c 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailTwoTimeTrackerState.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailTwoTimeTrackerState.java @@ -36,10 +36,15 @@ import org.zkoss.ganttz.util.Interval; */ public class DetailTwoTimeTrackerState extends TimeTrackerState { - public static final DetailTwoTimeTrackerState INSTANCE = new DetailTwoTimeTrackerState(); private static final int FIRST_LEVEL_ITEM_SIZE = 400; private static final int SECOND_LEVEL_ITEM_SIZE = 100; + protected DetailTwoTimeTrackerState( + IDetailItemModificator firstLevelModificator, + IDetailItemModificator secondLevelModificator) { + super(firstLevelModificator, secondLevelModificator); + } + public final double daysPerPixel() { return ((double) 365 / FIRST_LEVEL_ITEM_SIZE); } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/TimeTrackerState.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/TimeTrackerState.java index 3fb7b0299..dc1fd2d15 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/TimeTrackerState.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/TimeTrackerState.java @@ -38,8 +38,14 @@ public abstract class TimeTrackerState { protected static final long MILLSECONDS_IN_DAY = 1000 * 60 * 60 * 24; protected static final int NUMBER_OF_ITEMS_MINIMUM = 10; - public Collection getFirstLevelDetails(Interval interval) { - return markEvens(createDetailsForFirstLevel(interval)); + private final IDetailItemModificator firstLevelModificator; + + private final IDetailItemModificator secondLevelModificator; + + protected TimeTrackerState(IDetailItemModificator firstLevelModificator, + IDetailItemModificator secondLevelModificator) { + this.firstLevelModificator = firstLevelModificator; + this.secondLevelModificator = secondLevelModificator; } // When applied after setting current day, removes extra data as current day @@ -65,7 +71,23 @@ public abstract class TimeTrackerState { public Collection getSecondLevelDetails(Interval interval) { // Also mark holidays and current date - return markEvens(createDetailsForSecondLevel(interval)); + return markEvens(applyConfiguredModifications(secondLevelModificator, + createDetailsForSecondLevel(interval))); + } + + public Collection getFirstLevelDetails(Interval interval) { + return markEvens(applyConfiguredModifications(firstLevelModificator, + createDetailsForFirstLevel(interval))); + } + + private static List applyConfiguredModifications( + IDetailItemModificator modificator, + Collection detailsItems) { + List result = new ArrayList(detailsItems.size()); + for (DetailItem each : detailsItems) { + result.add(modificator.applyModificationsTo(each)); + } + return result; } protected static int[] calculateInitialEndYear(Date initialDate, 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 822a9919b..1a2d58536 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 @@ -35,6 +35,12 @@ import org.zkoss.ganttz.util.Interval; */ public abstract class TimeTrackerStateUsingJodaTime extends TimeTrackerState { + TimeTrackerStateUsingJodaTime( + IDetailItemModificator firstLevelModificator, + IDetailItemModificator secondLevelModificator) { + super(firstLevelModificator, secondLevelModificator); + } + protected static LocalDate asLocalDate(Date date) { return new LocalDate(date); } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java index 99ba2c13f..eaa7f8e20 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java @@ -25,20 +25,46 @@ package org.zkoss.ganttz.timetracker.zoom; */ public enum ZoomLevel { - DETAIL_ONE(DetailOneTimeTrackerState.INSTANCE), DETAIL_TWO( - DetailTwoTimeTrackerState.INSTANCE), DETAIL_THREE( - DetailThreeTimeTrackerState.INSTANCE), DETAIL_FOUR( - DetailFourTimeTrackerState.INSTANCE), DETAIL_FIVE( - DetailFiveTimeTrackerState.INSTANCE); - - private final TimeTrackerState state; - - private ZoomLevel(TimeTrackerState state) { - if (state == null) { - throw new IllegalArgumentException("state cannot be null"); + DETAIL_ONE { + @Override + public TimeTrackerState getTimeTrackerState( + IDetailItemModificator firstLevel, + IDetailItemModificator secondLevel) { + return new DetailOneTimeTrackerState(firstLevel, secondLevel); } - this.state = state; - } + }, + DETAIL_TWO { + @Override + public TimeTrackerState getTimeTrackerState( + IDetailItemModificator firstLevel, + IDetailItemModificator secondLevel) { + return new DetailTwoTimeTrackerState(firstLevel, secondLevel); + } + }, + DETAIL_THREE { + @Override + public TimeTrackerState getTimeTrackerState( + IDetailItemModificator firstLevel, + IDetailItemModificator secondLevel) { + return new DetailThreeTimeTrackerState(firstLevel, secondLevel); + } + }, + DETAIL_FOUR { + @Override + public TimeTrackerState getTimeTrackerState( + IDetailItemModificator firstLevel, + IDetailItemModificator secondLevel) { + return new DetailFourTimeTrackerState(firstLevel, secondLevel); + } + }, + DETAIL_FIVE { + @Override + public TimeTrackerState getTimeTrackerState( + IDetailItemModificator firstLevel, + IDetailItemModificator secondLevel) { + return new DetailFiveTimeTrackerState(firstLevel, secondLevel); + } + }; /** * @return if there is no next, returns this. Otherwise returns @@ -63,8 +89,8 @@ public enum ZoomLevel { return ZoomLevel.values()[ordinal() - 1]; } - public TimeTrackerState getTimeTrackerState() { - return state; - } + public abstract TimeTrackerState getTimeTrackerState( + IDetailItemModificator firstLevel, + IDetailItemModificator secondLevel); }