/*
Copyright 2014 BarD Software s.r.o
This file is part of GanttProject, an opensource project management tool.
GanttProject 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.
GanttProject 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 GanttProject. If not, see <http://www.gnu.org/licenses/>.
*/
package net.sourceforge.ganttproject.chart;
import biz.ganttproject.core.chart.canvas.Canvas;
import biz.ganttproject.core.option.DefaultFontOption;
import biz.ganttproject.core.option.DefaultIntegerOption;
import biz.ganttproject.core.option.FontSpec;
import biz.ganttproject.core.time.impl.GPTimeUnitStack;
import com.google.common.collect.Lists;
import net.sourceforge.ganttproject.TestSetupHelper;
import net.sourceforge.ganttproject.chart.TaskRendererImpl2.VerticalPartitioning;
import net.sourceforge.ganttproject.gui.UIConfiguration;
import net.sourceforge.ganttproject.task.Task;
import net.sourceforge.ganttproject.task.TaskActivity;
import net.sourceforge.ganttproject.task.TaskManager;
import net.sourceforge.ganttproject.test.task.TaskTestCase;
import java.awt.*;
import java.util.Collections;
import java.util.List;
/**
* @author dbarashev (Dmitry Barashev)
*/
public class TaskRendererImplTest extends TaskTestCase {
private List<Task> createTasks(TaskManager taskManager, int count) {
List<Task> result = Lists.newArrayList();
for (int i = 0; i < count; i++) {
result.add(taskManager.newTaskBuilder().withId(i).build());
}
return result;
}
public void testVerticalPartitioningNoCollapsed() {
TaskManager taskManager = TestSetupHelper.newTaskManagerBuilder().build();
List<Task> allTasks = createTasks(taskManager, 10);
{
VerticalPartitioning partitioning = new TaskRendererImpl2.VerticalPartitioning(allTasks.subList(0, 10));
partitioning.build(taskManager.getTaskHierarchy());
assertTrue(partitioning.aboveViewport.isEmpty());
assertTrue(partitioning.belowViewport.isEmpty());
}
{
VerticalPartitioning partitioning = new TaskRendererImpl2.VerticalPartitioning(allTasks.subList(0, 5));
partitioning.build(taskManager.getTaskHierarchy());
assertTrue(partitioning.aboveViewport.isEmpty());
assertEquals(5, partitioning.belowViewport.size());
}
{
VerticalPartitioning partitioning = new TaskRendererImpl2.VerticalPartitioning(allTasks.subList(5, 10));
partitioning.build(taskManager.getTaskHierarchy());
assertEquals(5, partitioning.aboveViewport.size());
assertTrue(partitioning.belowViewport.isEmpty());
}
{
VerticalPartitioning partitioning = new TaskRendererImpl2.VerticalPartitioning(allTasks.subList(3, 7));
partitioning.build(taskManager.getTaskHierarchy());
assertEquals(3, partitioning.aboveViewport.size());
assertEquals(3, partitioning.belowViewport.size());
}
}
public void testVerticalPartitioningWithCollapsedTasks() {
TaskManager taskManager = TestSetupHelper.newTaskManagerBuilder().build();
List<Task> allTasks = createTasks(taskManager, 10);
allTasks.get(2).move(allTasks.get(1));
allTasks.get(1).move(allTasks.get(0));
allTasks.get(0).setExpand(false);
{
VerticalPartitioning partitioning = new TaskRendererImpl2.VerticalPartitioning(allTasks.subList(4, 10));
partitioning.build(taskManager.getTaskHierarchy());
assertEquals(2, partitioning.aboveViewport.size());
assertEquals(0, partitioning.aboveViewport.get(0).getTaskID());
assertEquals(3, partitioning.aboveViewport.get(1).getTaskID());
assertTrue(partitioning.belowViewport.isEmpty());
}
allTasks.get(7).move(allTasks.get(6));
allTasks.get(9).move(allTasks.get(8));
{
VerticalPartitioning partitioning = new TaskRendererImpl2.VerticalPartitioning(allTasks.subList(4, 6));
partitioning.build(taskManager.getTaskHierarchy());
assertEquals(2, partitioning.aboveViewport.size());
assertEquals(0, partitioning.aboveViewport.get(0).getTaskID());
assertEquals(3, partitioning.aboveViewport.get(1).getTaskID());
assertEquals(2, partitioning.belowViewport.size());
assertEquals(6, partitioning.belowViewport.get(0).getTaskID());
assertEquals(8, partitioning.belowViewport.get(1).getTaskID());
}
}
// Tests algorithm which partitions task activities into "before viewport", "inside viewport"
// and "after viewport" parts
public void testSplitOnBounds() {
Task task = createTask(TestSetupHelper.newFriday(), 5);
{
// Split on frame with frame start = task start
List<TaskActivity> activities = TaskRendererImpl2.splitOnBounds(
task.getActivities(), TestSetupHelper.newFriday().getTime(), TestSetupHelper.newMonday().getTime());
assertEquals(2, activities.size());
assertTrue(activities.get(0).isFirst());
assertEquals(TestSetupHelper.newFriday().getTime(), activities.get(0).getStart());
assertEquals(TestSetupHelper.newMonday().getTime(), activities.get(0).getEnd());
assertTrue(activities.get(1).isLast());
assertEquals(TestSetupHelper.newMonday().getTime(), activities.get(1).getStart());
assertEquals(TestSetupHelper.newWendesday().getTime(), activities.get(1).getEnd());
}
{
// Task crosses both frame borders
List<TaskActivity> activities = TaskRendererImpl2.splitOnBounds(
task.getActivities(), TestSetupHelper.newSaturday().getTime(), TestSetupHelper.newTuesday().getTime());
assertEquals(3, activities.size());
assertTrue(activities.get(0).isFirst());
assertEquals(TestSetupHelper.newFriday().getTime(), activities.get(0).getStart());
assertEquals(TestSetupHelper.newSaturday().getTime(), activities.get(0).getEnd());
assertFalse(activities.get(1).isFirst());
assertFalse(activities.get(1).isLast());
assertEquals(TestSetupHelper.newSaturday().getTime(), activities.get(1).getStart());
assertEquals(TestSetupHelper.newTuesday().getTime(), activities.get(1).getEnd());
assertTrue(activities.get(2).isLast());
assertEquals(TestSetupHelper.newTuesday().getTime(), activities.get(2).getStart());
assertEquals(TestSetupHelper.newWendesday().getTime(), activities.get(2).getEnd());
}
{
// Split on frame with frame end = task end
List<TaskActivity> activities = TaskRendererImpl2.splitOnBounds(
task.getActivities(), TestSetupHelper.newMonday().getTime(), TestSetupHelper.newWendesday().getTime());
assertEquals(2, activities.size());
assertTrue(activities.get(0).isFirst());
assertEquals(TestSetupHelper.newFriday().getTime(), activities.get(0).getStart());
assertEquals(TestSetupHelper.newMonday().getTime(), activities.get(0).getEnd());
assertTrue(activities.get(1).isLast());
assertEquals(TestSetupHelper.newMonday().getTime(), activities.get(1).getStart());
assertEquals(TestSetupHelper.newWendesday().getTime(), activities.get(1).getEnd());
}
}
public void testGetTaskRectangles() {
Task t = createTask(TestSetupHelper.newMonday());
{
t.setColor(Color.RED);
t.setDuration(getTaskManager().createLength(4));
}
ChartModelImpl chartModel;
{
// Setup chart with start date on Wednesday, size 200x200, weeks as big unit, days as small unit
UIConfiguration projectConfig = new UIConfiguration(Color.BLACK, false);
projectConfig.setChartFontOption(new DefaultFontOption("foo", new FontSpec("Foo", FontSpec.Size.HUGE), Collections.<String>emptyList()));
projectConfig.setDpiOption(new DefaultIntegerOption("bar", 96));
chartModel = new ChartModelImpl(getTaskManager(), new GPTimeUnitStack(), projectConfig);
chartModel.setStartDate(TestSetupHelper.newWendesday().getTime());
chartModel.setVisibleTasks(Lists.newArrayList(t));
chartModel.setBounds(new Dimension(200, 200));
chartModel.setTopTimeUnit(GPTimeUnitStack.WEEK);
chartModel.setBottomTimeUnit(GPTimeUnitStack.DAY);
chartModel.setBottomUnitWidth(20);
}
TaskRendererImpl2 renderer = new TaskRendererImpl2(chartModel);
chartModel.addRenderer(renderer);
renderer.render();
// We expect that renderer will create two rectangles for our task, one "invisible" (before chart start date)
// and one visible
List<Canvas.Rectangle> rectangles = TaskRendererImpl2.getTaskRectangles(t, chartModel);
assertEquals(2, rectangles.size());
TaskActivity part1 = (TaskActivity) rectangles.get(0).getModelObject();
assertNotNull(part1);
assertEquals(TestSetupHelper.newMonday().getTime(), part1.getStart());
assertEquals(TestSetupHelper.newWendesday().getTime(), part1.getEnd());
TaskActivity part2 = (TaskActivity) rectangles.get(1).getModelObject();
assertNotNull(part2);
assertEquals(TestSetupHelper.newWendesday().getTime(), part2.getStart());
assertEquals(2, part2.getDuration().getLength());
}
}