From 9da0fd0939d323b0f02cb975e66a8da177f94d0c Mon Sep 17 00:00:00 2001 From: Arnaud Roques Date: Thu, 18 Aug 2022 18:55:09 +0200 Subject: [PATCH] Gantt improvement --- .../plantuml/project/GanttDiagram.java | 82 +++--- .../plantuml/project/GanttDiagramFactory.java | 19 +- .../project/TimeHeaderParameters.java | 133 +++++++++ .../plantuml/project/ToTaskDraw.java | 3 + .../project/command/CommandGroupEnd.java | 68 +++++ .../project/command/CommandGroupStart.java | 71 +++++ .../plantuml/project/core/TaskGroup.java | 136 ++++++++++ .../project/draw/AbstractTaskDraw.java | 16 +- .../project/draw/TaskDrawDiamond.java | 5 +- .../plantuml/project/draw/TaskDrawGroup.java | 256 ++++++++++++++++++ .../project/draw/TaskDrawRegular.java | 6 +- .../plantuml/project/draw/TimeHeader.java | 16 +- .../project/draw/TimeHeaderCalendar.java | 50 ++-- .../project/draw/TimeHeaderDaily.java | 75 ++--- .../project/draw/TimeHeaderMonthly.java | 29 +- .../project/draw/TimeHeaderQuarterly.java | 25 +- .../project/draw/TimeHeaderSimple.java | 39 ++- .../project/draw/TimeHeaderWeekly.java | 31 +-- .../project/draw/TimeHeaderYearly.java | 21 +- ...lementBeforeOrAfterOrAtTaskStartOrEnd.java | 24 +- .../project/lang/SubjectSeparator.java | 113 ++++++++ .../plantuml/project/lang/Verbs.java | 12 + .../timescale/TimeScaleCompressed.java | 2 +- .../project/timescale/TimeScaleDaily.java | 9 +- .../sourceforge/plantuml/version/Version.java | 2 +- 25 files changed, 1007 insertions(+), 236 deletions(-) create mode 100644 src/net/sourceforge/plantuml/project/TimeHeaderParameters.java create mode 100644 src/net/sourceforge/plantuml/project/command/CommandGroupEnd.java create mode 100644 src/net/sourceforge/plantuml/project/command/CommandGroupStart.java create mode 100644 src/net/sourceforge/plantuml/project/core/TaskGroup.java create mode 100644 src/net/sourceforge/plantuml/project/draw/TaskDrawGroup.java create mode 100644 src/net/sourceforge/plantuml/project/lang/SubjectSeparator.java diff --git a/src/net/sourceforge/plantuml/project/GanttDiagram.java b/src/net/sourceforge/plantuml/project/GanttDiagram.java index 3669d0591..8399e83a1 100644 --- a/src/net/sourceforge/plantuml/project/GanttDiagram.java +++ b/src/net/sourceforge/plantuml/project/GanttDiagram.java @@ -42,11 +42,13 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -74,6 +76,7 @@ import net.sourceforge.plantuml.project.core.Resource; import net.sourceforge.plantuml.project.core.Task; import net.sourceforge.plantuml.project.core.TaskAttribute; import net.sourceforge.plantuml.project.core.TaskCode; +import net.sourceforge.plantuml.project.core.TaskGroup; import net.sourceforge.plantuml.project.core.TaskImpl; import net.sourceforge.plantuml.project.core.TaskInstant; import net.sourceforge.plantuml.project.core.TaskSeparator; @@ -81,6 +84,7 @@ import net.sourceforge.plantuml.project.draw.FingerPrint; import net.sourceforge.plantuml.project.draw.ResourceDraw; import net.sourceforge.plantuml.project.draw.TaskDraw; import net.sourceforge.plantuml.project.draw.TaskDrawDiamond; +import net.sourceforge.plantuml.project.draw.TaskDrawGroup; import net.sourceforge.plantuml.project.draw.TaskDrawRegular; import net.sourceforge.plantuml.project.draw.TaskDrawSeparator; import net.sourceforge.plantuml.project.draw.TimeHeader; @@ -296,33 +300,28 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit private TimeHeader getTimeHeader() { if (openClose.getStartingDay() == null) - return new TimeHeaderSimple(printScale, getTimelineStyle(), getClosedStyle(), getFactorScale(), min, max, - getIHtmlColorSet(), getSkinParam().getThemeStyle(), colorDays()); + return new TimeHeaderSimple(thParam(), printScale); else if (printScale == PrintScale.DAILY) - return new TimeHeaderDaily(locale, getTimelineStyle(), getClosedStyle(), getFactorScale(), - openClose.getStartingDay(), min, max, openClose, colorDays(), colorDaysOfWeek, nameDays, printStart, - printEnd, getIHtmlColorSet(), getSkinParam().getThemeStyle()); + return new TimeHeaderDaily(thParam(), nameDays, printStart, printEnd); else if (printScale == PrintScale.WEEKLY) - return new TimeHeaderWeekly(weekNumberStrategy, withCalendarDate, locale, getTimelineStyle(), - getClosedStyle(), getFactorScale(), openClose.getStartingDay(), min, max, openClose, colorDays(), - colorDaysOfWeek, getIHtmlColorSet(), getSkinParam().getThemeStyle()); + return new TimeHeaderWeekly(thParam(), weekNumberStrategy, withCalendarDate); else if (printScale == PrintScale.MONTHLY) - return new TimeHeaderMonthly(locale, getTimelineStyle(), getClosedStyle(), getFactorScale(), - openClose.getStartingDay(), min, max, openClose, colorDays(), colorDaysOfWeek, getIHtmlColorSet(), - getSkinParam().getThemeStyle()); + return new TimeHeaderMonthly(thParam()); else if (printScale == PrintScale.QUARTERLY) - return new TimeHeaderQuarterly(locale, getTimelineStyle(), getClosedStyle(), getFactorScale(), - openClose.getStartingDay(), min, max, openClose, colorDays(), colorDaysOfWeek, getIHtmlColorSet(), - getSkinParam().getThemeStyle()); + return new TimeHeaderQuarterly(thParam()); else if (printScale == PrintScale.YEARLY) - return new TimeHeaderYearly(locale, getTimelineStyle(), getClosedStyle(), getFactorScale(), - openClose.getStartingDay(), min, max, openClose, colorDays(), colorDaysOfWeek, getIHtmlColorSet(), - getSkinParam().getThemeStyle()); + return new TimeHeaderYearly(thParam()); else throw new IllegalStateException(); } + private TimeHeaderParameters thParam() { + return new TimeHeaderParameters(colorDays(), getSkinParam().getThemeStyle(), getFactorScale(), min, max, + getIHtmlColorSet(), getTimelineStyle(), getClosedStyle(), locale, openClose, colorDaysOfWeek, + verticalSeparatorBefore); + } + private Map colorDays() { colorDaysInternal.putAll(colorDaysToday); return Collections.unmodifiableMap(colorDaysInternal); @@ -425,26 +424,30 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit for (Task task : tasks.values()) { final TaskDraw draw; if (task instanceof TaskSeparator) { - draw = new TaskDrawSeparator(((TaskSeparator) task).getName(), timeScale, y, min, max, - task.getStyleBuilder(), getSkinParam().getIHtmlColorSet()); + final TaskSeparator taskSeparator = (TaskSeparator) task; + draw = new TaskDrawSeparator(taskSeparator.getName(), timeScale, y, min, max, task.getStyleBuilder(), + getSkinParam().getIHtmlColorSet()); + } else if (task instanceof TaskGroup) { + final TaskGroup taskGroup = (TaskGroup) task; + draw = new TaskDrawGroup(timeScale, y, taskGroup.getCode().getSimpleDisplay(), getStart(taskGroup), + getEnd(taskGroup), getSkinParam(), task, this, task.getStyleBuilder()); } else { final TaskImpl tmp = (TaskImpl) task; final String disp = hideRessourceName ? tmp.getCode().getSimpleDisplay() : tmp.getPrettyDisplay(); if (tmp.isDiamond()) { draw = new TaskDrawDiamond(timeScale, y, disp, getStart(tmp), getSkinParam(), task, this, - task.getStyleBuilder(), getSkinParam().getIHtmlColorSet()); + task.getStyleBuilder()); } else { final boolean oddStart = printStart != null && min.compareTo(getStart(tmp)) == 0; final boolean oddEnd = printStart != null && max.compareTo(getEnd(tmp)) == 0; draw = new TaskDrawRegular(timeScale, y, disp, getStart(tmp), getEnd(tmp), oddStart, oddEnd, - getSkinParam(), task, this, getConstraints(task), task.getStyleBuilder(), - getSkinParam().getIHtmlColorSet()); + getSkinParam(), task, this, getConstraints(task), task.getStyleBuilder()); } draw.setColorsAndCompletion(tmp.getColors(), tmp.getCompletion(), tmp.getUrl(), tmp.getNote()); } - if (task.getRow() == null) { + if (task.getRow() == null) y = y.addAtLeast(draw.getFullHeightTask(stringBounder)); - } + draws.put(task, draw); } origin.compileNow(); @@ -504,17 +507,17 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit } } - private Day getStart(final TaskImpl tmp) { - if (printStart == null) { + private Day getStart(final Task tmp) { + if (printStart == null) return tmp.getStart(); - } + return Day.max(min, tmp.getStart()); } - private Day getEnd(final TaskImpl tmp) { - if (printStart == null) { + private Day getEnd(final Task tmp) { + if (printStart == null) return tmp.getEnd(); - } + return Day.min(max, tmp.getEnd()); } @@ -524,7 +527,7 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit } else { max = null; for (Task task : tasks.values()) { - if (task instanceof TaskSeparator) + if (task instanceof TaskSeparator || task instanceof TaskGroup) continue; final Day start = task.getStart(); @@ -601,6 +604,9 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit result = new TaskImpl(getSkinParam().getCurrentStyleBuilder(), code, openClose.mutateMe(except), openClose.getStartingDay()); + if (currentGroup != null) + currentGroup.addTask(result); + tasks.put(code, result); if (byShortName != null) byShortName.put(shortName, result); @@ -626,6 +632,14 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit tasks.put(separator.getCode(), separator); } + private TaskGroup currentGroup = null; + + public void addGroup(String comment) { + TaskGroup group = new TaskGroup(getSkinParam().getCurrentStyleBuilder(), comment); + currentGroup = group; + tasks.put(group.getCode(), group); + } + public void addContraint(GanttConstraint constraint) { constraints.add(constraint); } @@ -820,4 +834,10 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit return CommandExecutionResult.ok(); } + private final Set verticalSeparatorBefore = new HashSet<>(); + + public void addVerticalSeparatorBefore(Day day) { + verticalSeparatorBefore.add(day); + } + } diff --git a/src/net/sourceforge/plantuml/project/GanttDiagramFactory.java b/src/net/sourceforge/plantuml/project/GanttDiagramFactory.java index 914a92fed..b378158fa 100644 --- a/src/net/sourceforge/plantuml/project/GanttDiagramFactory.java +++ b/src/net/sourceforge/plantuml/project/GanttDiagramFactory.java @@ -52,6 +52,8 @@ import net.sourceforge.plantuml.project.command.CommandColorTask; import net.sourceforge.plantuml.project.command.CommandFootbox; import net.sourceforge.plantuml.project.command.CommandGanttArrow; import net.sourceforge.plantuml.project.command.CommandGanttArrow2; +import net.sourceforge.plantuml.project.command.CommandGroupEnd; +import net.sourceforge.plantuml.project.command.CommandGroupStart; import net.sourceforge.plantuml.project.command.CommandHideRessourceFootbox; import net.sourceforge.plantuml.project.command.CommandHideRessourceName; import net.sourceforge.plantuml.project.command.CommandLabelOnColumn; @@ -71,6 +73,7 @@ import net.sourceforge.plantuml.project.lang.SubjectDayOfWeek; import net.sourceforge.plantuml.project.lang.SubjectDaysAsDates; import net.sourceforge.plantuml.project.lang.SubjectProject; import net.sourceforge.plantuml.project.lang.SubjectResource; +import net.sourceforge.plantuml.project.lang.SubjectSeparator; import net.sourceforge.plantuml.project.lang.SubjectTask; import net.sourceforge.plantuml.project.lang.SubjectToday; import net.sourceforge.plantuml.style.CommandStyleImport; @@ -80,7 +83,8 @@ public class GanttDiagramFactory extends PSystemCommandFactory { static private final List subjects() { return Arrays.asList(new SubjectTask(), new SubjectProject(), new SubjectDayOfWeek(), - new SubjectDayAsDate(), new SubjectDaysAsDates(), new SubjectResource(), new SubjectToday()); + new SubjectDayAsDate(), new SubjectDaysAsDates(), new SubjectResource(), new SubjectToday(), + new SubjectSeparator()); } public GanttDiagramFactory(DiagramType type) { @@ -96,16 +100,17 @@ public class GanttDiagramFactory extends PSystemCommandFactory { cmds.add(new CommandStyleMultilinesCSS()); cmds.add(new CommandStyleImport()); - // addCommonCommands(cmds); cmds.add(new CommandNope()); - // cmds.add(new CommandComment()); - // cmds.add(new CommandMultilinesComment()); + cmds.addAll(getLanguageCommands()); + cmds.add(new CommandGanttArrow()); cmds.add(new CommandGanttArrow2()); cmds.add(new CommandColorTask()); cmds.add(new CommandSeparator()); cmds.add(new CommandWeekNumberStrategy()); + cmds.add(new CommandGroupStart()); + cmds.add(new CommandGroupEnd()); cmds.add(new CommandLanguage()); cmds.add(new CommandPrintScale()); @@ -116,12 +121,6 @@ public class GanttDiagramFactory extends PSystemCommandFactory { cmds.add(new CommandHideRessourceName()); cmds.add(new CommandHideRessourceFootbox()); - // cmds.add(new CommandScaleWidthAndHeight()); - // cmds.add(new CommandScaleWidthOrHeight()); - // cmds.add(new CommandScaleMaxWidth()); - // cmds.add(new CommandScaleMaxHeight()); - // cmds.add(new CommandScaleMaxWidthAndHeight()); - return cmds; } diff --git a/src/net/sourceforge/plantuml/project/TimeHeaderParameters.java b/src/net/sourceforge/plantuml/project/TimeHeaderParameters.java new file mode 100644 index 000000000..19d9af37c --- /dev/null +++ b/src/net/sourceforge/plantuml/project/TimeHeaderParameters.java @@ -0,0 +1,133 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2023, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML 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. + * + * PlantUML 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.project; + +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +import net.sourceforge.plantuml.api.ThemeStyle; +import net.sourceforge.plantuml.project.time.Day; +import net.sourceforge.plantuml.project.time.DayOfWeek; +import net.sourceforge.plantuml.style.Style; +import net.sourceforge.plantuml.ugraphic.color.HColor; +import net.sourceforge.plantuml.ugraphic.color.HColorSet; + +public class TimeHeaderParameters { + + private final Map colorDays; + private final ThemeStyle themeStyle; + private final double scale; + private final Day min; + private final Day max; + private final HColorSet colorSet; + private final Style timelineStyle; + private final Style closedStyle; + private final Locale locale; + private final OpenClose openClose; + private final Map colorDaysOfWeek; + private final Set verticalSeparatorBefore; + + public TimeHeaderParameters(Map colorDays, ThemeStyle themeStyle, double scale, Day min, Day max, + HColorSet colorSet, Style timelineStyle, Style closedStyle, Locale locale, OpenClose openClose, + Map colorDaysOfWeek, Set verticalSeparatorBefore) { + this.colorDays = colorDays; + this.themeStyle = themeStyle; + this.scale = scale; + this.min = min; + this.max = max; + this.colorSet = colorSet; + this.timelineStyle = timelineStyle; + this.closedStyle = closedStyle; + this.locale = locale; + this.openClose = openClose; + this.colorDaysOfWeek = colorDaysOfWeek; + this.verticalSeparatorBefore = verticalSeparatorBefore; + } + + public HColor getColor(Day wink) { + return colorDays.get(wink); + } + + public HColor getColor(DayOfWeek dayOfWeek) { + return colorDaysOfWeek.get(dayOfWeek); + } + + public ThemeStyle getThemeStyle() { + return themeStyle; + } + + public final double getScale() { + return scale; + } + + public final Day getMin() { + return min; + } + + public final Day getMax() { + return max; + } + + public final HColorSet getColorSet() { + return colorSet; + } + + public final Style getTimelineStyle() { + return timelineStyle; + } + + public final Style getClosedStyle() { + return closedStyle; + } + + public final Locale getLocale() { + return locale; + } + + public final LoadPlanable getLoadPlanable() { + return openClose; + } + + public Day getStartingDay() { + return openClose.getStartingDay(); + } + + public final Set getVerticalSeparatorBefore() { + return verticalSeparatorBefore; + } + +} diff --git a/src/net/sourceforge/plantuml/project/ToTaskDraw.java b/src/net/sourceforge/plantuml/project/ToTaskDraw.java index 85adff470..46c5db059 100644 --- a/src/net/sourceforge/plantuml/project/ToTaskDraw.java +++ b/src/net/sourceforge/plantuml/project/ToTaskDraw.java @@ -37,6 +37,7 @@ package net.sourceforge.plantuml.project; import net.sourceforge.plantuml.project.core.Task; import net.sourceforge.plantuml.project.draw.TaskDraw; +import net.sourceforge.plantuml.ugraphic.color.HColorSet; public interface ToTaskDraw { @@ -44,4 +45,6 @@ public interface ToTaskDraw { public LoadPlanable getDefaultPlan(); + public HColorSet getIHtmlColorSet(); + } diff --git a/src/net/sourceforge/plantuml/project/command/CommandGroupEnd.java b/src/net/sourceforge/plantuml/project/command/CommandGroupEnd.java new file mode 100644 index 000000000..823976234 --- /dev/null +++ b/src/net/sourceforge/plantuml/project/command/CommandGroupEnd.java @@ -0,0 +1,68 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2023, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML 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. + * + * PlantUML 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.project.command; + +import net.sourceforge.plantuml.LineLocation; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand2; +import net.sourceforge.plantuml.command.regex.IRegex; +import net.sourceforge.plantuml.command.regex.RegexConcat; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexResult; +import net.sourceforge.plantuml.project.GanttDiagram; + +public class CommandGroupEnd extends SingleLineCommand2 { + + public CommandGroupEnd() { + super(getRegexConcat()); + } + + static IRegex getRegexConcat() { + return RegexConcat.build(CommandGroupEnd.class.getName(), RegexLeaf.start(), // + RegexLeaf.spaceZeroOrMore(), // + new RegexLeaf("end"), // + RegexLeaf.spaceZeroOrMore(), // + new RegexLeaf("group"), // + RegexLeaf.spaceZeroOrMore(), // + RegexLeaf.end()); + } + + @Override + protected CommandExecutionResult executeArg(GanttDiagram diagram, LineLocation location, RegexResult arg) { + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/project/command/CommandGroupStart.java b/src/net/sourceforge/plantuml/project/command/CommandGroupStart.java new file mode 100644 index 000000000..45bbd415f --- /dev/null +++ b/src/net/sourceforge/plantuml/project/command/CommandGroupStart.java @@ -0,0 +1,71 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2023, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML 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. + * + * PlantUML 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.project.command; + +import net.sourceforge.plantuml.LineLocation; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand2; +import net.sourceforge.plantuml.command.regex.IRegex; +import net.sourceforge.plantuml.command.regex.RegexConcat; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexResult; +import net.sourceforge.plantuml.project.GanttDiagram; + +public class CommandGroupStart extends SingleLineCommand2 { + + public CommandGroupStart() { + super(getRegexConcat()); + } + + static IRegex getRegexConcat() { + return RegexConcat.build(CommandGroupStart.class.getName(), RegexLeaf.start(), // + new RegexLeaf("group"), // + RegexLeaf.spaceOneOrMore(), // + new RegexLeaf("\\["), // + new RegexLeaf("NAME", "([^\\[\\]]+)"), // + new RegexLeaf("\\]"), // + RegexLeaf.spaceZeroOrMore(), // + RegexLeaf.end()); + } + + @Override + protected CommandExecutionResult executeArg(GanttDiagram diagram, LineLocation location, RegexResult arg) { + final String name = arg.get("NAME", 0); + diagram.addGroup(name); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/project/core/TaskGroup.java b/src/net/sourceforge/plantuml/project/core/TaskGroup.java new file mode 100644 index 000000000..8dc45e558 --- /dev/null +++ b/src/net/sourceforge/plantuml/project/core/TaskGroup.java @@ -0,0 +1,136 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2023, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML 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. + * + * PlantUML 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.project.core; + +import java.util.ArrayList; +import java.util.List; + +import net.sourceforge.plantuml.Url; +import net.sourceforge.plantuml.cucadiagram.Display; +import net.sourceforge.plantuml.project.Load; +import net.sourceforge.plantuml.project.lang.CenterBorderColor; +import net.sourceforge.plantuml.project.time.Day; +import net.sourceforge.plantuml.project.time.DayOfWeek; +import net.sourceforge.plantuml.style.StyleBuilder; + +public class TaskGroup extends AbstractTask implements Task { + + private final List children = new ArrayList<>(); + + public TaskGroup(StyleBuilder styleBuilder, String comment) { + super(styleBuilder, new TaskCode(comment)); + } + + public Day getStart() { + Day min = null; + for (Task child : children) + if (min == null || min.compareTo(child.getStart()) > 0) + min = child.getStart(); + + if (min != null) + return min; + + throw new UnsupportedOperationException(); + } + + public Day getEnd() { + Day max = null; + for (Task child : children) + if (max == null || max.compareTo(child.getEnd()) < 0) + max = child.getEnd(); + + if (max != null) + return max; + + throw new UnsupportedOperationException(); + } + + public void setStart(Day start) { + throw new UnsupportedOperationException(); + } + + public void setEnd(Day end) { + throw new UnsupportedOperationException(); + } + + public void setColors(CenterBorderColor... colors) { + throw new UnsupportedOperationException(); + } + + public void addResource(Resource resource, int percentage) { + throw new UnsupportedOperationException(); + } + + public Load getLoad() { + throw new UnsupportedOperationException(); + } + + public void setLoad(Load load) { + throw new UnsupportedOperationException(); + } + + public void setDiamond(boolean diamond) { + throw new UnsupportedOperationException(); + } + + public boolean isDiamond() { + throw new UnsupportedOperationException(); + } + + public void setCompletion(int completion) { + throw new UnsupportedOperationException(); + } + + public void setUrl(Url url) { + throw new UnsupportedOperationException(); + } + + public void addPause(Day pause) { + throw new UnsupportedOperationException(); + } + + public void addPause(DayOfWeek pause) { + throw new UnsupportedOperationException(); + } + + public void setNote(Display note) { + } + + public void addTask(Task child) { + children.add(child); + } + +} diff --git a/src/net/sourceforge/plantuml/project/draw/AbstractTaskDraw.java b/src/net/sourceforge/plantuml/project/draw/AbstractTaskDraw.java index bec8e89eb..97e65965a 100644 --- a/src/net/sourceforge/plantuml/project/draw/AbstractTaskDraw.java +++ b/src/net/sourceforge/plantuml/project/draw/AbstractTaskDraw.java @@ -70,7 +70,6 @@ public abstract class AbstractTaskDraw implements TaskDraw { protected final String prettyDisplay; protected final Day start; private final StyleBuilder styleBuilder; - private final HColorSet colorSet; private final Task task; private final ToTaskDraw toTaskDraw; @@ -87,9 +86,8 @@ public abstract class AbstractTaskDraw implements TaskDraw { } public AbstractTaskDraw(TimeScale timeScale, Real y, String prettyDisplay, Day start, ISkinParam skinParam, - Task task, ToTaskDraw toTaskDraw, StyleBuilder styleBuilder, HColorSet colorSet) { + Task task, ToTaskDraw toTaskDraw, StyleBuilder styleBuilder) { this.y = y; - this.colorSet = colorSet; this.styleBuilder = styleBuilder; this.toTaskDraw = toTaskDraw; this.start = start; @@ -106,22 +104,22 @@ public abstract class AbstractTaskDraw implements TaskDraw { final protected HColor getLineColor() { final HColor unstarted = getStyleSignatureUnstarted().getMergedStyle(styleBuilder).value(PName.LineColor) - .asColor(getStyleBuilder().getSkinParam().getThemeStyle(), colorSet); + .asColor(getStyleBuilder().getSkinParam().getThemeStyle(), getColorSet()); final HColor regular = getStyle().value(PName.LineColor) - .asColor(getStyleBuilder().getSkinParam().getThemeStyle(), colorSet); + .asColor(getStyleBuilder().getSkinParam().getThemeStyle(), getColorSet()); return HColorUtils.unlinear(unstarted, regular, completion); } final protected HColor getBackgroundColor() { final HColor unstarted = getStyleSignatureUnstarted().getMergedStyle(styleBuilder).value(PName.BackGroundColor) - .asColor(getStyleBuilder().getSkinParam().getThemeStyle(), colorSet); + .asColor(getStyleBuilder().getSkinParam().getThemeStyle(), getColorSet()); final HColor regular = getStyle().value(PName.BackGroundColor) - .asColor(getStyleBuilder().getSkinParam().getThemeStyle(), colorSet); + .asColor(getStyleBuilder().getSkinParam().getThemeStyle(), getColorSet()); return HColorUtils.unlinear(unstarted, regular, completion); } final protected FontConfiguration getFontConfiguration() { - return getStyle().getFontConfiguration(styleBuilder.getSkinParam().getThemeStyle(), colorSet); + return getStyle().getFontConfiguration(styleBuilder.getSkinParam().getThemeStyle(), getColorSet()); } final protected Style getStyle() { @@ -184,7 +182,7 @@ public abstract class AbstractTaskDraw implements TaskDraw { } protected final HColorSet getColorSet() { - return colorSet; + return toTaskDraw.getIHtmlColorSet(); } protected CenterBorderColor getColors() { diff --git a/src/net/sourceforge/plantuml/project/draw/TaskDrawDiamond.java b/src/net/sourceforge/plantuml/project/draw/TaskDrawDiamond.java index f23fe7365..f8f1d0a58 100644 --- a/src/net/sourceforge/plantuml/project/draw/TaskDrawDiamond.java +++ b/src/net/sourceforge/plantuml/project/draw/TaskDrawDiamond.java @@ -59,13 +59,12 @@ import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UPolygon; import net.sourceforge.plantuml.ugraphic.UShape; import net.sourceforge.plantuml.ugraphic.UTranslate; -import net.sourceforge.plantuml.ugraphic.color.HColorSet; public class TaskDrawDiamond extends AbstractTaskDraw { public TaskDrawDiamond(TimeScale timeScale, Real y, String prettyDisplay, Day start, ISkinParam skinParam, - Task task, ToTaskDraw toTaskDraw, StyleBuilder styleBuilder, HColorSet colorSet) { - super(timeScale, y, prettyDisplay, start, skinParam, task, toTaskDraw, styleBuilder, colorSet); + Task task, ToTaskDraw toTaskDraw, StyleBuilder styleBuilder) { + super(timeScale, y, prettyDisplay, start, skinParam, task, toTaskDraw, styleBuilder); } @Override diff --git a/src/net/sourceforge/plantuml/project/draw/TaskDrawGroup.java b/src/net/sourceforge/plantuml/project/draw/TaskDrawGroup.java new file mode 100644 index 000000000..192898cff --- /dev/null +++ b/src/net/sourceforge/plantuml/project/draw/TaskDrawGroup.java @@ -0,0 +1,256 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2023, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML 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. + * + * PlantUML 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.project.draw; + +import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.SpriteContainerEmpty; +import net.sourceforge.plantuml.awt.geom.Dimension2D; +import net.sourceforge.plantuml.cucadiagram.Display; +import net.sourceforge.plantuml.graphic.HorizontalAlignment; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.project.LabelStrategy; +import net.sourceforge.plantuml.project.ToTaskDraw; +import net.sourceforge.plantuml.project.core.Task; +import net.sourceforge.plantuml.project.core.TaskAttribute; +import net.sourceforge.plantuml.project.lang.CenterBorderColor; +import net.sourceforge.plantuml.project.time.Day; +import net.sourceforge.plantuml.project.timescale.TimeScale; +import net.sourceforge.plantuml.real.Real; +import net.sourceforge.plantuml.style.ClockwiseTopRightBottomLeft; +import net.sourceforge.plantuml.style.SName; +import net.sourceforge.plantuml.style.Style; +import net.sourceforge.plantuml.style.StyleBuilder; +import net.sourceforge.plantuml.style.StyleSignatureBasic; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.UPath; +import net.sourceforge.plantuml.ugraphic.URectangle; +import net.sourceforge.plantuml.ugraphic.UShape; +import net.sourceforge.plantuml.ugraphic.UTranslate; +import net.sourceforge.plantuml.ugraphic.color.HColorUtils; + +public class TaskDrawGroup extends AbstractTaskDraw { + + private final Day end; + + private final ISkinParam skinParam; + + public TaskDrawGroup(TimeScale timeScale, Real y, String prettyDisplay, Day start, Day end, ISkinParam skinParam, + Task task, ToTaskDraw toTaskDraw, StyleBuilder styleBuilder) { + super(timeScale, y, prettyDisplay, start, skinParam, task, toTaskDraw, styleBuilder); + this.skinParam = skinParam; + this.end = end; + } + + @Override + protected double getShapeHeight(StringBounder stringBounder) { + final Style style = getStyle(); + final ClockwiseTopRightBottomLeft padding = style.getPadding(); + return padding.getTop() + getTitle().calculateDimension(stringBounder).getHeight() + padding.getBottom() + 8; + } + + @Override + public void drawTitle(UGraphic ug, LabelStrategy labelStrategy, double colTitles, double colBars) { + final TextBlock title = getTitle(); + final StringBounder stringBounder = ug.getStringBounder(); + final Dimension2D dim = title.calculateDimension(stringBounder); + + final Style style = getStyleSignature().getMergedStyle(getStyleBuilder()); + final ClockwiseTopRightBottomLeft margin = style.getMargin(); + final ClockwiseTopRightBottomLeft padding = style.getPadding(); + + ug = ug.apply(UTranslate.dy(margin.getTop() + padding.getTop())); + +// if (labelStrategy.titleInFirstColumn()) { +// if (labelStrategy.rightAligned()) +// title.drawU(ug.apply(UTranslate.dx(colTitles - dim.getWidth() - margin.getRight()))); +// else +// title.drawU(ug.apply(UTranslate.dx(margin.getLeft()))); +// return; +// } else if (labelStrategy.titleInLastColumn()) { +// title.drawU(ug.apply(UTranslate.dx(colBars + margin.getLeft()))); +// return; +// } +// + final double pos1 = timeScale.getStartingPosition(start) + 6; + final double pos2 = timeScale.getEndingPosition(end) - 6; + final double pos; + if (pos2 - pos1 > dim.getWidth()) + pos = pos1 + (pos2 - pos1 - dim.getWidth()) / 2; + else + pos = pos2 + 3; + title.drawU(ug.apply(UTranslate.dx(pos))); + } + + @Override + protected TextBlock getTitle() { + return Display.getWithNewlines(prettyDisplay).create(getFontConfiguration(), HorizontalAlignment.LEFT, + new SpriteContainerEmpty()); + } + + @Override + StyleSignatureBasic getStyleSignature() { + return StyleSignatureBasic.of(SName.root, SName.element, SName.ganttDiagram, SName.task); + } + + public void drawU(UGraphic ug) { + final double startPos = timeScale.getStartingPosition(start); + ug = applyColors(ug); + drawShape(ug); + } + + @Override + public double getHeightMax(StringBounder stringBounder) { + return getFullHeightTask(stringBounder); + } + + public FingerPrint getFingerPrint(StringBounder stringBounder) { + final double h = getFullHeightTask(stringBounder); + final double startPos = timeScale.getStartingPosition(start); + final double endPos = timeScale.getEndingPosition(end); + return new FingerPrint(startPos, getY(stringBounder).getCurrentValue(), endPos - startPos, h); + } + + public FingerPrint getFingerPrintNote(StringBounder stringBounder) { + return null; + } + + private UGraphic applyColors(UGraphic ug) { + final CenterBorderColor col = this.getColors(); + if (col != null && col.isOk()) + return col.apply(ug); + + return ug.apply(getLineColor()).apply(getBackgroundColor().bg()); + } + + public double getX1(TaskAttribute taskAttribute) { + final Style style = getStyleSignature().getMergedStyle(getStyleBuilder()); + final ClockwiseTopRightBottomLeft margin = style.getMargin(); + final double startPos = taskAttribute == TaskAttribute.START ? timeScale.getStartingPosition(start) + : timeScale.getStartingPosition(end) + margin.getLeft(); + return startPos; + } + + public double getX2(TaskAttribute taskAttribute) { + final Style style = getStyleSignature().getMergedStyle(getStyleBuilder()); + final ClockwiseTopRightBottomLeft margin = style.getMargin(); + final double endPos = taskAttribute == TaskAttribute.START ? timeScale.getEndingPosition(start) + : timeScale.getEndingPosition(end) - margin.getLeft(); + return endPos; + } + + private void drawShape(UGraphic ug) { + final Style style = getStyleSignature().getMergedStyle(getStyleBuilder()); + final ClockwiseTopRightBottomLeft margin = style.getMargin(); + + final double startPos = timeScale.getStartingPosition(start) + margin.getLeft(); + final double endPos = timeScale.getEndingPosition(end) - margin.getRight(); + + if (url != null) + ug.startUrl(url); + + // ug = ug.apply(UTranslate.dy(margin.getTop() + 7)); + ug = ug.apply(UTranslate.dy(getShapeHeight(ug.getStringBounder()) - 10)); + + ug = ug.apply(HColorUtils.BLACK).apply(HColorUtils.BLACK.bg()); + ug.draw(getShape(startPos, endPos)); + + if (url != null) + ug.closeUrl(); + + } + + private UPath getShape(final double startPos, final double endPos) { + final UPath rect = new UPath(); + + final double height = 10; + final double thick = 2; + final double y1 = (height - thick) / 2; + final double y2 = height - (height - thick) / 2; + final double dx = 6; + + rect.moveTo(startPos, 0); + rect.lineTo(startPos + dx, y1); + rect.lineTo(endPos - dx, y1); + rect.lineTo(endPos, 0); + rect.lineTo(endPos, height); + rect.lineTo(endPos - dx, y2); + rect.lineTo(startPos + dx, y2); + rect.lineTo(startPos, height); + rect.lineTo(startPos, 0); + + rect.closePath(); + return rect; + } + + private UPath getShapeOld2(final double startPos, final double endPos) { + final UPath rect = new UPath(); + + final double height1 = 9; + final double height2 = 7; + final double dx = 6; + + rect.moveTo(startPos, 0); + rect.lineTo(startPos + dx, height2); + rect.lineTo(endPos - dx, height2); + rect.lineTo(endPos, 0); + rect.lineTo(endPos, height1); + rect.lineTo(startPos, height1); + rect.lineTo(startPos, 0); + + rect.closePath(); + return rect; + } + + private UPath getShapeOld(final double startPos, final double endPos) { + final UPath rect = new UPath(); + + final double height1 = 9; + final double height2 = 2; + final double dx = 6; + + rect.moveTo(startPos, 0); + rect.lineTo(endPos, 0); + rect.lineTo(endPos, height1); + rect.lineTo(endPos - dx, height2); + rect.lineTo(startPos + dx, height2); + rect.lineTo(startPos, height1); + rect.lineTo(startPos, 0); + rect.closePath(); + return rect; + } + +} diff --git a/src/net/sourceforge/plantuml/project/draw/TaskDrawRegular.java b/src/net/sourceforge/plantuml/project/draw/TaskDrawRegular.java index 1720822be..8fbd1fbfa 100644 --- a/src/net/sourceforge/plantuml/project/draw/TaskDrawRegular.java +++ b/src/net/sourceforge/plantuml/project/draw/TaskDrawRegular.java @@ -73,7 +73,6 @@ import net.sourceforge.plantuml.svek.image.Opale; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UTranslate; import net.sourceforge.plantuml.ugraphic.color.HColor; -import net.sourceforge.plantuml.ugraphic.color.HColorSet; public class TaskDrawRegular extends AbstractTaskDraw { @@ -86,8 +85,8 @@ public class TaskDrawRegular extends AbstractTaskDraw { public TaskDrawRegular(TimeScale timeScale, Real y, String prettyDisplay, Day start, Day end, boolean oddStart, boolean oddEnd, ISkinParam skinParam, Task task, ToTaskDraw toTaskDraw, - Collection constraints, StyleBuilder styleBuilder, HColorSet colorSet) { - super(timeScale, y, prettyDisplay, start, skinParam, task, toTaskDraw, styleBuilder, colorSet); + Collection constraints, StyleBuilder styleBuilder) { + super(timeScale, y, prettyDisplay, start, skinParam, task, toTaskDraw, styleBuilder); this.skinParam = skinParam; this.constraints = constraints; this.end = end; @@ -190,6 +189,7 @@ public class TaskDrawRegular extends AbstractTaskDraw { } + @Override public double getHeightMax(StringBounder stringBounder) { if (note == null) return getFullHeightTask(stringBounder); diff --git a/src/net/sourceforge/plantuml/project/draw/TimeHeader.java b/src/net/sourceforge/plantuml/project/draw/TimeHeader.java index 154f7d116..97c4ac05f 100644 --- a/src/net/sourceforge/plantuml/project/draw/TimeHeader.java +++ b/src/net/sourceforge/plantuml/project/draw/TimeHeader.java @@ -51,10 +51,12 @@ import net.sourceforge.plantuml.ugraphic.UFont; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.ULine; import net.sourceforge.plantuml.ugraphic.URectangle; +import net.sourceforge.plantuml.ugraphic.UStroke; import net.sourceforge.plantuml.ugraphic.UTranslate; import net.sourceforge.plantuml.ugraphic.color.HColor; import net.sourceforge.plantuml.ugraphic.color.HColorNone; import net.sourceforge.plantuml.ugraphic.color.HColorSet; +import net.sourceforge.plantuml.ugraphic.color.HColorUtils; public abstract class TimeHeader { @@ -120,9 +122,13 @@ public abstract class TimeHeader { ug.apply(getBarColor()).apply(UTranslate.dy(y)).draw(hline); } - protected final void drawVbar(UGraphic ug, double x, double y1, double y2) { + protected final void drawVbar(UGraphic ug, double x, double y1, double y2, boolean bold) { final ULine vbar = ULine.vline(y2 - y1); - ug.apply(getBarColor()).apply(new UTranslate(x, y1)).draw(vbar); + if (bold) + ug = goBold(ug); + else + ug = ug.apply(getBarColor()); + ug.apply(new UTranslate(x, y1)).draw(vbar); } final protected FontConfiguration getFontConfiguration(int size, boolean bold, HColor color) { @@ -171,5 +177,11 @@ public abstract class TimeHeader { ug = ug.apply(new UTranslate(x1, getFullHeaderHeight())); ug.draw(new URectangle(x2 - x1, height)); } + + protected final UGraphic goBold(UGraphic ug) { + return ug.apply(HColorUtils.BLACK).apply(new UStroke(2)); + } + + } diff --git a/src/net/sourceforge/plantuml/project/draw/TimeHeaderCalendar.java b/src/net/sourceforge/plantuml/project/draw/TimeHeaderCalendar.java index dbdee2e64..94c0aa3cf 100644 --- a/src/net/sourceforge/plantuml/project/draw/TimeHeaderCalendar.java +++ b/src/net/sourceforge/plantuml/project/draw/TimeHeaderCalendar.java @@ -36,33 +36,29 @@ package net.sourceforge.plantuml.project.draw; import java.util.Locale; -import java.util.Map; -import net.sourceforge.plantuml.api.ThemeStyle; -import net.sourceforge.plantuml.project.LoadPlanable; +import net.sourceforge.plantuml.project.TimeHeaderParameters; import net.sourceforge.plantuml.project.time.Day; -import net.sourceforge.plantuml.project.time.DayOfWeek; import net.sourceforge.plantuml.project.timescale.TimeScale; -import net.sourceforge.plantuml.style.Style; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.color.HColor; -import net.sourceforge.plantuml.ugraphic.color.HColorSet; public abstract class TimeHeaderCalendar extends TimeHeader { - protected final LoadPlanable defaultPlan; - protected final Map colorDays; - protected final Map colorDaysOfWeek; - protected final Locale locale; + private final TimeHeaderParameters thParam; - public TimeHeaderCalendar(Locale locale, Style timelineStyle, Style closedStyle, Day calendar, Day min, Day max, - LoadPlanable defaultPlan, Map colorDays, Map colorDaysOfWeek, - TimeScale timeScale, HColorSet colorSet, ThemeStyle themeStyle) { - super(timelineStyle, closedStyle, min, max, timeScale, colorSet, themeStyle); - this.locale = locale; - this.defaultPlan = defaultPlan; - this.colorDays = colorDays; - this.colorDaysOfWeek = colorDaysOfWeek; + public TimeHeaderCalendar(TimeHeaderParameters thParam, TimeScale timeScale) { + super(thParam.getTimelineStyle(), thParam.getClosedStyle(), thParam.getMin(), thParam.getMax(), timeScale, + thParam.getColorSet(), thParam.getThemeStyle()); + this.thParam = thParam; + } + + protected final Locale locale() { + return thParam.getLocale(); + } + + protected final int getLoadAt(Day instant) { + return thParam.getLoadPlanable().getLoadAt(instant); } // Duplicate in TimeHeaderSimple @@ -90,15 +86,15 @@ public abstract class TimeHeaderCalendar extends TimeHeader { for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment()) { final double x1 = getTimeScale().getStartingPosition(wink); final double x2 = getTimeScale().getEndingPosition(wink); - HColor back = colorDays.get(wink); + HColor back = thParam.getColor(wink); // Day of week should be stronger than period of time (back color). - final HColor backDoW = colorDaysOfWeek.get(wink.getDayOfWeek()); - if (backDoW != null) { + final HColor backDoW = thParam.getColor(wink.getDayOfWeek()); + if (backDoW != null) back = backDoW; - } - if (back == null && defaultPlan.getLoadAt(wink) == 0) { + + if (back == null && getLoadAt(wink) == 0) back = closedBackgroundColor(); - } + if (back == null) { if (pending != null) pending.draw(ug, height); @@ -108,11 +104,11 @@ public abstract class TimeHeaderCalendar extends TimeHeader { pending.draw(ug, height); pending = null; } - if (pending == null) { + if (pending == null) pending = new Pending(back, x1, x2); - } else { + else pending.x2 = x2; - } + } } } diff --git a/src/net/sourceforge/plantuml/project/draw/TimeHeaderDaily.java b/src/net/sourceforge/plantuml/project/draw/TimeHeaderDaily.java index 2b94f60e0..fe687f9f8 100644 --- a/src/net/sourceforge/plantuml/project/draw/TimeHeaderDaily.java +++ b/src/net/sourceforge/plantuml/project/draw/TimeHeaderDaily.java @@ -35,21 +35,17 @@ */ package net.sourceforge.plantuml.project.draw; -import java.util.Locale; import java.util.Map; +import java.util.Set; -import net.sourceforge.plantuml.api.ThemeStyle; import net.sourceforge.plantuml.graphic.TextBlock; -import net.sourceforge.plantuml.project.LoadPlanable; +import net.sourceforge.plantuml.project.TimeHeaderParameters; import net.sourceforge.plantuml.project.time.Day; -import net.sourceforge.plantuml.project.time.DayOfWeek; import net.sourceforge.plantuml.project.time.MonthYear; import net.sourceforge.plantuml.project.timescale.TimeScaleDaily; -import net.sourceforge.plantuml.style.Style; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UTranslate; import net.sourceforge.plantuml.ugraphic.color.HColor; -import net.sourceforge.plantuml.ugraphic.color.HColorSet; public class TimeHeaderDaily extends TimeHeaderCalendar { @@ -63,13 +59,16 @@ public class TimeHeaderDaily extends TimeHeaderCalendar { } private final Map nameDays; + private final Set verticalSeparators; - public TimeHeaderDaily(Locale locale, Style timelineStyle, Style closedStyle, double scale, Day calendar, Day min, - Day max, LoadPlanable defaultPlan, Map colorDays, Map colorDaysOfWeek, - Map nameDays, Day printStart, Day printEnd, HColorSet colorSet, ThemeStyle themeStyle) { - super(locale, timelineStyle, closedStyle, calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek, - new TimeScaleDaily(scale, calendar, printStart), colorSet, themeStyle); + public TimeHeaderDaily(TimeHeaderParameters thParam, Map nameDays, Day printStart, Day printEnd) { + super(thParam, new TimeScaleDaily(thParam.getStartingDay(), thParam.getScale(), printStart)); this.nameDays = nameDays; + this.verticalSeparators = thParam.getVerticalSeparatorBefore(); + } + + private boolean isBold(Day wink) { + return verticalSeparators.contains(wink); } @Override @@ -79,37 +78,19 @@ public class TimeHeaderDaily extends TimeHeaderCalendar { drawTextDayOfMonth(ug.apply(UTranslate.dy(Y_POS_ROW28()))); drawMonths(ug); printSmallVbars(ug, totalHeightWithoutFooter); -// drawVBars(ug, totalHeightWithoutFooter); -// drawVbar(ug, getTimeScale().getStartingPosition(max.increment()), 0, -// totalHeightWithoutFooter + getTimeFooterHeight()); + printNamedDays(ug); drawHline(ug, getFullHeaderHeight()); drawHline(ug, totalHeightWithoutFooter); - -// drawHline(ug, 0); -// drawHline(ug, getFullHeaderHeight()); } private void printSmallVbars(final UGraphic ug, double totalHeightWithoutFooter) { - for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment()) { - drawVbar(ug, getTimeScale().getStartingPosition(wink), getFullHeaderHeight(), totalHeightWithoutFooter); - } - drawVbar(ug, getTimeScale().getEndingPosition(max), getFullHeaderHeight(), totalHeightWithoutFooter); - } + for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment()) + drawVbar(ug, getTimeScale().getStartingPosition(wink), getFullHeaderHeight(), totalHeightWithoutFooter, + isBold(wink)); - private void drawVBars(UGraphic ug, double totalHeightWithoutFooter) { - MonthYear last = null; - for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment()) { - double startingY = getFullHeaderHeight(); - double len = totalHeightWithoutFooter; - if (wink.monthYear().equals(last) == false) { - startingY = 0; - last = wink.monthYear(); - len += 24 + 13; - } - drawVbar(ug, getTimeScale().getStartingPosition(wink), startingY, len); - } + drawVbar(ug, getTimeScale().getEndingPosition(max), getFullHeaderHeight(), totalHeightWithoutFooter, false); } @Override @@ -117,8 +98,6 @@ public class TimeHeaderDaily extends TimeHeaderCalendar { drawTextDayOfMonth(ug.apply(UTranslate.dy(12))); drawTextsDayOfWeek(ug); drawMonths(ug.apply(UTranslate.dy(24))); -// drawHline(ug, 0); -// drawHline(ug, getTimeFooterHeight()); } private void drawTextsDayOfWeek(UGraphic ug) { @@ -126,7 +105,7 @@ public class TimeHeaderDaily extends TimeHeaderCalendar { final double x1 = getTimeScale().getStartingPosition(wink); final double x2 = getTimeScale().getEndingPosition(wink); final HColor textColor = getTextBackColor(wink); - printCentered(ug, getTextBlock(wink.getDayOfWeek().shortName(locale), 10, false, textColor), x1, x2); + printCentered(ug, getTextBlock(wink.getDayOfWeek().shortName(locale()), 10, false, textColor), x1, x2); } } @@ -140,9 +119,9 @@ public class TimeHeaderDaily extends TimeHeaderCalendar { } private HColor getTextBackColor(Day wink) { - if (defaultPlan.getLoadAt(wink) <= 0) { + if (getLoadAt(wink) <= 0) return closedFontColor(); - } + return openFontColor(); } @@ -152,23 +131,23 @@ public class TimeHeaderDaily extends TimeHeaderCalendar { for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment()) { final double x1 = getTimeScale().getStartingPosition(wink); if (wink.monthYear().equals(last) == false) { - if (last != null) { + if (last != null) printMonth(ug, last, lastChangeMonth, x1); - } + lastChangeMonth = x1; last = wink.monthYear(); } } final double x1 = getTimeScale().getStartingPosition(max.increment()); - if (x1 > lastChangeMonth) { + if (x1 > lastChangeMonth) printMonth(ug, last, lastChangeMonth, x1); - } + } private void printMonth(UGraphic ug, MonthYear monthYear, double start, double end) { - final TextBlock tiny = getTextBlock(monthYear.shortName(locale), 12, true, openFontColor()); - final TextBlock small = getTextBlock(monthYear.longName(locale), 12, true, openFontColor()); - final TextBlock big = getTextBlock(monthYear.longNameYYYY(locale), 12, true, openFontColor()); + final TextBlock tiny = getTextBlock(monthYear.shortName(locale()), 12, true, openFontColor()); + final TextBlock small = getTextBlock(monthYear.longName(locale()), 12, true, openFontColor()); + final TextBlock big = getTextBlock(monthYear.longNameYYYY(locale()), 12, true, openFontColor()); printCentered(ug, false, start, end, tiny, small, big); } @@ -197,9 +176,9 @@ public class TimeHeaderDaily extends TimeHeaderCalendar { } private double getHeaderNameDayHeight() { - if (nameDays.size() > 0) { + if (nameDays.size() > 0) return 16; - } + return 0; } diff --git a/src/net/sourceforge/plantuml/project/draw/TimeHeaderMonthly.java b/src/net/sourceforge/plantuml/project/draw/TimeHeaderMonthly.java index d79573254..32f355350 100644 --- a/src/net/sourceforge/plantuml/project/draw/TimeHeaderMonthly.java +++ b/src/net/sourceforge/plantuml/project/draw/TimeHeaderMonthly.java @@ -35,21 +35,13 @@ */ package net.sourceforge.plantuml.project.draw; -import java.util.Locale; -import java.util.Map; - -import net.sourceforge.plantuml.api.ThemeStyle; import net.sourceforge.plantuml.graphic.TextBlock; -import net.sourceforge.plantuml.project.LoadPlanable; +import net.sourceforge.plantuml.project.TimeHeaderParameters; import net.sourceforge.plantuml.project.time.Day; -import net.sourceforge.plantuml.project.time.DayOfWeek; import net.sourceforge.plantuml.project.time.MonthYear; import net.sourceforge.plantuml.project.timescale.TimeScaleCompressed; -import net.sourceforge.plantuml.style.Style; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UTranslate; -import net.sourceforge.plantuml.ugraphic.color.HColor; -import net.sourceforge.plantuml.ugraphic.color.HColorSet; public class TimeHeaderMonthly extends TimeHeaderCalendar { @@ -61,11 +53,8 @@ public class TimeHeaderMonthly extends TimeHeaderCalendar { return 16 + 13 - 1; } - public TimeHeaderMonthly(Locale locale, Style timelineStyle, Style closedStyle, double scale, Day calendar, Day min, - Day max, LoadPlanable defaultPlan, Map colorDays, Map colorDaysOfWeek, - HColorSet colorSet, ThemeStyle themeStyle) { - super(locale, timelineStyle, closedStyle, calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek, - new TimeScaleCompressed(calendar, scale), colorSet, themeStyle); + public TimeHeaderMonthly(TimeHeaderParameters thParam) { + super(thParam, new TimeScaleCompressed(thParam.getStartingDay(), thParam.getScale())); } @Override @@ -94,7 +83,7 @@ public class TimeHeaderMonthly extends TimeHeaderCalendar { for (Day wink = min; wink.compareTo(max) < 0; wink = wink.increment()) { final double x1 = getTimeScale().getStartingPosition(wink); if (last == null || wink.monthYear().year() != last.year()) { - drawVbar(ug, x1, 0, 15); + drawVbar(ug, x1, 0, 15, false); if (last != null) { printYear(ug, last, lastChange, x1); } @@ -106,7 +95,7 @@ public class TimeHeaderMonthly extends TimeHeaderCalendar { if (x1 > lastChange) { printYear(ug, last, lastChange, x1); } - drawVbar(ug, getTimeScale().getEndingPosition(max), 0, 15); + drawVbar(ug, getTimeScale().getEndingPosition(max), 0, 15, false); } private void drawMonths(UGraphic ug) { @@ -115,7 +104,7 @@ public class TimeHeaderMonthly extends TimeHeaderCalendar { for (Day wink = min; wink.compareTo(max) < 0; wink = wink.increment()) { final double x1 = getTimeScale().getStartingPosition(wink); if (wink.monthYear().equals(last) == false) { - drawVbar(ug, x1, 0, 12); + drawVbar(ug, x1, 0, 12, false); if (last != null) { printMonth(ug, last, lastChange, x1); } @@ -127,7 +116,7 @@ public class TimeHeaderMonthly extends TimeHeaderCalendar { if (x1 > lastChange) { printMonth(ug, last, lastChange, x1); } - drawVbar(ug, getTimeScale().getEndingPosition(max), 0, 12); + drawVbar(ug, getTimeScale().getEndingPosition(max), 0, 12, false); } private void printYear(UGraphic ug, MonthYear monthYear, double start, double end) { @@ -136,8 +125,8 @@ public class TimeHeaderMonthly extends TimeHeaderCalendar { } private void printMonth(UGraphic ug, MonthYear monthYear, double start, double end) { - final TextBlock small = getTextBlock(monthYear.shortName(locale), 10, false, openFontColor()); - final TextBlock big = getTextBlock(monthYear.longName(locale), 10, false, openFontColor()); + final TextBlock small = getTextBlock(monthYear.shortName(locale()), 10, false, openFontColor()); + final TextBlock big = getTextBlock(monthYear.longName(locale()), 10, false, openFontColor()); printCentered(ug, false, start, end, small, big); } diff --git a/src/net/sourceforge/plantuml/project/draw/TimeHeaderQuarterly.java b/src/net/sourceforge/plantuml/project/draw/TimeHeaderQuarterly.java index 38d64c274..5dfdaee71 100644 --- a/src/net/sourceforge/plantuml/project/draw/TimeHeaderQuarterly.java +++ b/src/net/sourceforge/plantuml/project/draw/TimeHeaderQuarterly.java @@ -35,21 +35,13 @@ */ package net.sourceforge.plantuml.project.draw; -import java.util.Locale; -import java.util.Map; - -import net.sourceforge.plantuml.api.ThemeStyle; import net.sourceforge.plantuml.graphic.TextBlock; -import net.sourceforge.plantuml.project.LoadPlanable; +import net.sourceforge.plantuml.project.TimeHeaderParameters; import net.sourceforge.plantuml.project.time.Day; -import net.sourceforge.plantuml.project.time.DayOfWeek; import net.sourceforge.plantuml.project.time.MonthYear; import net.sourceforge.plantuml.project.timescale.TimeScaleCompressed; -import net.sourceforge.plantuml.style.Style; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UTranslate; -import net.sourceforge.plantuml.ugraphic.color.HColor; -import net.sourceforge.plantuml.ugraphic.color.HColorSet; public class TimeHeaderQuarterly extends TimeHeaderCalendar { @@ -61,11 +53,8 @@ public class TimeHeaderQuarterly extends TimeHeaderCalendar { return 16 + 13 - 1; } - public TimeHeaderQuarterly(Locale locale, Style timelineStyle, Style closedStyle, double scale, Day calendar, Day min, Day max, - LoadPlanable defaultPlan, Map colorDays, Map colorDaysOfWeek, - HColorSet colorSet, ThemeStyle themeStyle) { - super(locale, timelineStyle, closedStyle, calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek, - new TimeScaleCompressed(calendar, scale), colorSet, themeStyle); + public TimeHeaderQuarterly(TimeHeaderParameters thParam) { + super(thParam, new TimeScaleCompressed(thParam.getStartingDay(), thParam.getScale())); } @Override @@ -94,7 +83,7 @@ public class TimeHeaderQuarterly extends TimeHeaderCalendar { for (Day wink = min; wink.compareTo(max) < 0; wink = wink.increment()) { final double x1 = getTimeScale().getStartingPosition(wink); if (last == null || wink.monthYear().year() != last.year()) { - drawVbar(ug, x1, 0, 15); + drawVbar(ug, x1, 0, 15, false); if (last != null) { printYear(ug, last, lastChange, x1); } @@ -106,7 +95,7 @@ public class TimeHeaderQuarterly extends TimeHeaderCalendar { if (x1 > lastChange) { printYear(ug, last, lastChange, x1); } - drawVbar(ug, getTimeScale().getEndingPosition(max), 0, 15); + drawVbar(ug, getTimeScale().getEndingPosition(max), 0, 15, false); } private void drawQuarters(UGraphic ug) { @@ -115,7 +104,7 @@ public class TimeHeaderQuarterly extends TimeHeaderCalendar { for (Day wink = min; wink.compareTo(max) < 0; wink = wink.increment()) { final double x1 = getTimeScale().getStartingPosition(wink); if (quarter(wink).equals(last) == false) { - drawVbar(ug, x1, 0, 12); + drawVbar(ug, x1, 0, 12, false); if (last != null) { printQuarter(ug, last, lastChange, x1); } @@ -127,7 +116,7 @@ public class TimeHeaderQuarterly extends TimeHeaderCalendar { if (x1 > lastChange) { printQuarter(ug, last, lastChange, x1); } - drawVbar(ug, getTimeScale().getEndingPosition(max), 0, 12); + drawVbar(ug, getTimeScale().getEndingPosition(max), 0, 12, false); } private String quarter(Day day) { diff --git a/src/net/sourceforge/plantuml/project/draw/TimeHeaderSimple.java b/src/net/sourceforge/plantuml/project/draw/TimeHeaderSimple.java index ec2c0318d..98d512213 100644 --- a/src/net/sourceforge/plantuml/project/draw/TimeHeaderSimple.java +++ b/src/net/sourceforge/plantuml/project/draw/TimeHeaderSimple.java @@ -35,28 +35,27 @@ */ package net.sourceforge.plantuml.project.draw; -import java.util.Map; +import java.util.Set; import net.sourceforge.plantuml.SpriteContainerEmpty; -import net.sourceforge.plantuml.api.ThemeStyle; import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.graphic.HorizontalAlignment; import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.project.TimeHeaderParameters; import net.sourceforge.plantuml.project.core.PrintScale; import net.sourceforge.plantuml.project.time.Day; import net.sourceforge.plantuml.project.timescale.TimeScale; import net.sourceforge.plantuml.project.timescale.TimeScaleWink; -import net.sourceforge.plantuml.style.Style; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.ULine; import net.sourceforge.plantuml.ugraphic.UTranslate; import net.sourceforge.plantuml.ugraphic.color.HColor; -import net.sourceforge.plantuml.ugraphic.color.HColorSet; public class TimeHeaderSimple extends TimeHeader { - private final Map colorDays; + private final TimeHeaderParameters colorDays; private final PrintScale printScale; + private final Set verticalSeparators; @Override public double getFullHeaderHeight() { @@ -75,11 +74,26 @@ public class TimeHeaderSimple extends TimeHeader { return 0; } - public TimeHeaderSimple(PrintScale printScale, Style timelineStyle, Style closedStyle, double scale, Day min, - Day max, HColorSet colorSet, ThemeStyle themeStyle, Map colorDays) { - super(timelineStyle, closedStyle, min, max, new TimeScaleWink(scale, printScale), colorSet, themeStyle); - this.colorDays = colorDays; + public TimeHeaderSimple(TimeHeaderParameters thParam, PrintScale printScale) { + super(thParam.getTimelineStyle(), thParam.getClosedStyle(), thParam.getMin(), thParam.getMax(), + new TimeScaleWink(thParam.getScale(), printScale), thParam.getColorSet(), thParam.getThemeStyle()); + this.colorDays = thParam; this.printScale = printScale; + this.verticalSeparators = thParam.getVerticalSeparatorBefore(); + } + + private boolean isBold(Day wink) { + return verticalSeparators.contains(wink); + } + + private void drawSeparatorsDay(UGraphic ug, TimeScale timeScale, double totalHeightWithoutFooter) { + final ULine vbar = ULine.vline(totalHeightWithoutFooter - getFullHeaderHeight() + 2); + ug = goBold(ug).apply(UTranslate.dy(getFullHeaderHeight() - 1)); + for (Day i = min; i.compareTo(max.increment()) <= 0; i = i.increment(printScale)) + if (isBold(i)) { + final double x1 = timeScale.getStartingPosition(i); + ug.apply(UTranslate.dx(x1)).draw(vbar); + } } private void drawSmallVlinesDay(UGraphic ug, TimeScale timeScale, double totalHeightWithoutFooter) { @@ -119,7 +133,8 @@ public class TimeHeaderSimple extends TimeHeader { drawTextsBackground(ug.apply(UTranslate.dy(-3)), totalHeightWithoutFooter + 6); final double xmin = getTimeScale().getStartingPosition(min); final double xmax = getTimeScale().getEndingPosition(max); - drawSmallVlinesDay(ug, getTimeScale(), totalHeightWithoutFooter); + drawSmallVlinesDay(ug, getTimeScale(), totalHeightWithoutFooter + 2); + drawSeparatorsDay(ug, getTimeScale(), totalHeightWithoutFooter); drawSimpleDayCounter(ug, getTimeScale()); ug.apply(getBarColor()).draw(ULine.hline(xmax - xmin)); ug.apply(getBarColor()).apply(UTranslate.dy(getFullHeaderHeight() - 3)).draw(ULine.hline(xmax - xmin)); @@ -130,8 +145,8 @@ public class TimeHeaderSimple extends TimeHeader { public void drawTimeFooter(UGraphic ug) { final double xmin = getTimeScale().getStartingPosition(min); final double xmax = getTimeScale().getEndingPosition(max); - drawSmallVlinesDay(ug, getTimeScale(), getTimeFooterHeight()); ug = ug.apply(UTranslate.dy(3)); + drawSmallVlinesDay(ug, getTimeScale(), getTimeFooterHeight() - 3); drawSimpleDayCounter(ug, getTimeScale()); ug.apply(getBarColor()).draw(ULine.hline(xmax - xmin)); } @@ -161,7 +176,7 @@ public class TimeHeaderSimple extends TimeHeader { for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment()) { final double x1 = getTimeScale().getStartingPosition(wink); final double x2 = getTimeScale().getEndingPosition(wink); - HColor back = colorDays.get(wink); + HColor back = colorDays.getColor(wink); // // Day of week should be stronger than period of time (back color). // final HColor backDoW = colorDaysOfWeek.get(wink.getDayOfWeek()); // if (backDoW != null) { diff --git a/src/net/sourceforge/plantuml/project/draw/TimeHeaderWeekly.java b/src/net/sourceforge/plantuml/project/draw/TimeHeaderWeekly.java index 8348f214d..3efb8e866 100644 --- a/src/net/sourceforge/plantuml/project/draw/TimeHeaderWeekly.java +++ b/src/net/sourceforge/plantuml/project/draw/TimeHeaderWeekly.java @@ -35,22 +35,14 @@ */ package net.sourceforge.plantuml.project.draw; -import java.util.Locale; -import java.util.Map; - -import net.sourceforge.plantuml.api.ThemeStyle; import net.sourceforge.plantuml.graphic.TextBlock; -import net.sourceforge.plantuml.project.LoadPlanable; +import net.sourceforge.plantuml.project.TimeHeaderParameters; import net.sourceforge.plantuml.project.time.Day; -import net.sourceforge.plantuml.project.time.DayOfWeek; import net.sourceforge.plantuml.project.time.MonthYear; import net.sourceforge.plantuml.project.time.WeekNumberStrategy; import net.sourceforge.plantuml.project.timescale.TimeScaleCompressed; -import net.sourceforge.plantuml.style.Style; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UTranslate; -import net.sourceforge.plantuml.ugraphic.color.HColor; -import net.sourceforge.plantuml.ugraphic.color.HColorSet; public class TimeHeaderWeekly extends TimeHeaderCalendar { @@ -65,12 +57,9 @@ public class TimeHeaderWeekly extends TimeHeaderCalendar { return 16; } - public TimeHeaderWeekly(WeekNumberStrategy weekNumberStrategy, boolean withCalendarDate, Locale locale, Style timelineStyle, - Style closedStyle, double scale, Day calendar, Day min, Day max, LoadPlanable defaultPlan, - Map colorDays, Map colorDaysOfWeek, HColorSet colorSet, - ThemeStyle themeStyle) { - super(locale, timelineStyle, closedStyle, calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek, - new TimeScaleCompressed(calendar, scale), colorSet, themeStyle); + public TimeHeaderWeekly(TimeHeaderParameters thParam, WeekNumberStrategy weekNumberStrategy, + boolean withCalendarDate) { + super(thParam, new TimeScaleCompressed(thParam.getStartingDay(), thParam.getScale())); this.weekNumberStrategy = weekNumberStrategy; this.withCalendarDate = withCalendarDate; } @@ -103,7 +92,7 @@ public class TimeHeaderWeekly extends TimeHeaderCalendar { for (Day wink = min; wink.compareTo(max) < 0; wink = wink.increment()) { final double x1 = getTimeScale().getStartingPosition(wink); if (wink.monthYear().equals(last) == false) { - drawVbar(ug, x1, 0, Y_POS_ROW16()); + drawVbar(ug, x1, 0, Y_POS_ROW16(), false); if (last != null) { printMonth(ug, last, lastChangeMonth, x1); } @@ -111,7 +100,7 @@ public class TimeHeaderWeekly extends TimeHeaderCalendar { last = wink.monthYear(); } } - drawVbar(ug, getTimeScale().getEndingPosition(max), 0, Y_POS_ROW16()); + drawVbar(ug, getTimeScale().getEndingPosition(max), 0, Y_POS_ROW16(), false); final double x1 = getTimeScale().getStartingPosition(max.increment()); if (x1 > lastChangeMonth) { printMonth(ug, last, lastChangeMonth, x1); @@ -121,10 +110,10 @@ public class TimeHeaderWeekly extends TimeHeaderCalendar { private void printSmallVbars(final UGraphic ug, double totalHeightWithoutFooter) { for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment()) { if (wink.getDayOfWeek() == weekNumberStrategy.getFirstDayOfWeek()) { - drawVbar(ug, getTimeScale().getStartingPosition(wink), Y_POS_ROW16(), totalHeightWithoutFooter); + drawVbar(ug, getTimeScale().getStartingPosition(wink), Y_POS_ROW16(), totalHeightWithoutFooter, false); } } - drawVbar(ug, getTimeScale().getEndingPosition(max), Y_POS_ROW16(), totalHeightWithoutFooter); + drawVbar(ug, getTimeScale().getEndingPosition(max), Y_POS_ROW16(), totalHeightWithoutFooter, false); } private void printDaysOfMonth(final UGraphic ug) { @@ -143,8 +132,8 @@ public class TimeHeaderWeekly extends TimeHeaderCalendar { } private void printMonth(UGraphic ug, MonthYear monthYear, double start, double end) { - final TextBlock small = getTextBlock(monthYear.shortName(locale), 12, true, openFontColor()); - final TextBlock big = getTextBlock(monthYear.shortNameYYYY(locale), 12, true, openFontColor()); + final TextBlock small = getTextBlock(monthYear.shortName(locale()), 12, true, openFontColor()); + final TextBlock big = getTextBlock(monthYear.shortNameYYYY(locale()), 12, true, openFontColor()); printCentered(ug, false, start, end, small, big); } diff --git a/src/net/sourceforge/plantuml/project/draw/TimeHeaderYearly.java b/src/net/sourceforge/plantuml/project/draw/TimeHeaderYearly.java index 9bc520e2e..1cec5ad40 100644 --- a/src/net/sourceforge/plantuml/project/draw/TimeHeaderYearly.java +++ b/src/net/sourceforge/plantuml/project/draw/TimeHeaderYearly.java @@ -35,21 +35,13 @@ */ package net.sourceforge.plantuml.project.draw; -import java.util.Locale; -import java.util.Map; - -import net.sourceforge.plantuml.api.ThemeStyle; import net.sourceforge.plantuml.graphic.TextBlock; -import net.sourceforge.plantuml.project.LoadPlanable; +import net.sourceforge.plantuml.project.TimeHeaderParameters; import net.sourceforge.plantuml.project.time.Day; -import net.sourceforge.plantuml.project.time.DayOfWeek; import net.sourceforge.plantuml.project.time.MonthYear; import net.sourceforge.plantuml.project.timescale.TimeScaleCompressed; -import net.sourceforge.plantuml.style.Style; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UTranslate; -import net.sourceforge.plantuml.ugraphic.color.HColor; -import net.sourceforge.plantuml.ugraphic.color.HColorSet; public class TimeHeaderYearly extends TimeHeaderCalendar { @@ -61,11 +53,8 @@ public class TimeHeaderYearly extends TimeHeaderCalendar { return 20 - 1; } - public TimeHeaderYearly(Locale locale, Style timelineStyle, Style closedStyle, double scale, Day calendar, Day min, Day max, - LoadPlanable defaultPlan, Map colorDays, Map colorDaysOfWeek, - HColorSet colorSet, ThemeStyle themeStyle) { - super(locale, timelineStyle, closedStyle, calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek, - new TimeScaleCompressed(calendar, scale), colorSet, themeStyle); + public TimeHeaderYearly(TimeHeaderParameters thParam) { + super(thParam, new TimeScaleCompressed(thParam.getStartingDay(), thParam.getScale())); } @Override @@ -90,7 +79,7 @@ public class TimeHeaderYearly extends TimeHeaderCalendar { for (Day wink = min; wink.compareTo(max) < 0; wink = wink.increment()) { final double x1 = getTimeScale().getStartingPosition(wink); if (last == null || wink.monthYear().year() != last.year()) { - drawVbar(ug, x1, 0, 19); + drawVbar(ug, x1, 0, 19, false); if (last != null) { printYear(ug, last, lastChange, x1); } @@ -102,7 +91,7 @@ public class TimeHeaderYearly extends TimeHeaderCalendar { if (x1 > lastChange) { printYear(ug, last, lastChange, x1); } - drawVbar(ug, getTimeScale().getEndingPosition(max), 0, 19); + drawVbar(ug, getTimeScale().getEndingPosition(max), 0, 19, false); } private void printYear(UGraphic ug, MonthYear monthYear, double start, double end) { diff --git a/src/net/sourceforge/plantuml/project/lang/ComplementBeforeOrAfterOrAtTaskStartOrEnd.java b/src/net/sourceforge/plantuml/project/lang/ComplementBeforeOrAfterOrAtTaskStartOrEnd.java index c80f13ad0..b9f594435 100644 --- a/src/net/sourceforge/plantuml/project/lang/ComplementBeforeOrAfterOrAtTaskStartOrEnd.java +++ b/src/net/sourceforge/plantuml/project/lang/ComplementBeforeOrAfterOrAtTaskStartOrEnd.java @@ -48,17 +48,19 @@ import net.sourceforge.plantuml.project.core.TaskInstant; public class ComplementBeforeOrAfterOrAtTaskStartOrEnd implements Something { private static final int POS_NB1 = 0; - private static final int POS_DAY_OR_WEEK1 = 1; - private static final int POS_NB2 = 2; - private static final int POS_DAY_OR_WEEK2 = 3; - private static final int POS_BEFORE_OR_AFTER = 4; - private static final int POS_CODE_OTHER = 5; - private static final int POS_START_OR_END = 6; + private static final int POS_WORKING1 = 1; + private static final int POS_DAY_OR_WEEK1 = 2; + private static final int POS_NB2 = 3; + private static final int POS_WORKING2 = 4; + private static final int POS_DAY_OR_WEEK2 = 5; + private static final int POS_BEFORE_OR_AFTER = 6; + private static final int POS_CODE_OTHER = 7; + private static final int POS_START_OR_END = 8; public IRegex toRegex(String suffix) { // "+" return new RegexLeaf("COMPLEMENT" + suffix, "(?:at|with|after|" + // - "(\\d+)[%s]+(day|week)s?" + // - "(?:[%s]+and[%s]+(\\d+)[%s]+(day|week)s?)?" + // + "(\\d+)[%s]+(working[%s]+)?(day|week)s?" + // + "(?:[%s]+and[%s]+(\\d+)[%s]+(working[%s]+)?(day|week)s?)?" + // "[%s]+(before|after))[%s]+\\[([^\\[\\]]+?)\\].?s[%s]+(start|end)"); } @@ -89,7 +91,11 @@ public class ComplementBeforeOrAfterOrAtTaskStartOrEnd implements Something { if ("before".equalsIgnoreCase(arg.get("COMPLEMENT" + suffix, POS_BEFORE_OR_AFTER))) delta = -delta; - final GanttConstraintMode mode = GanttConstraintMode.IGNORE_CALENDAR; + final boolean working = arg.get("COMPLEMENT" + suffix, POS_WORKING1) != null + || arg.get("COMPLEMENT" + suffix, POS_WORKING2) != null; + + final GanttConstraintMode mode = working ? GanttConstraintMode.DO_NOT_COUNT_CLOSE_DAY + : GanttConstraintMode.IGNORE_CALENDAR; result = result.withDelta(delta, mode, system.getDefaultPlan()); } diff --git a/src/net/sourceforge/plantuml/project/lang/SubjectSeparator.java b/src/net/sourceforge/plantuml/project/lang/SubjectSeparator.java new file mode 100644 index 000000000..695e4e3e1 --- /dev/null +++ b/src/net/sourceforge/plantuml/project/lang/SubjectSeparator.java @@ -0,0 +1,113 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2023, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML 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. + * + * PlantUML 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.project.lang; + +import java.util.Arrays; +import java.util.Collection; + +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.regex.IRegex; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexResult; +import net.sourceforge.plantuml.project.Failable; +import net.sourceforge.plantuml.project.GanttDiagram; +import net.sourceforge.plantuml.project.core.TaskInstant; +import net.sourceforge.plantuml.project.time.Day; + +public class SubjectSeparator implements Subject { + + public IRegex toRegex() { + return new RegexLeaf("SUBJECT", "separator"); + } + + public Failable getMe(GanttDiagram project, RegexResult arg) { + return Failable.ok(project); + } + + public Collection getSentences() { + return Arrays.asList(new JustBefore(), new JustAfter(), new Just()); + } + + class JustBefore extends SentenceSimple { + + public JustBefore() { + super(SubjectSeparator.this, Verbs.justBefore(), new ComplementDate()); + } + + @Override + public CommandExecutionResult execute(GanttDiagram project, Object subject, Object complement) { + final Day day = (Day) complement; + assert project == subject; + project.addVerticalSeparatorBefore(day); + return CommandExecutionResult.ok(); + } + + } + + class JustAfter extends SentenceSimple { + + public JustAfter() { + super(SubjectSeparator.this, Verbs.justAfter(), new ComplementDate()); + } + + @Override + public CommandExecutionResult execute(GanttDiagram project, Object subject, Object complement) { + final Day day = (Day) complement; + assert project == subject; + project.addVerticalSeparatorBefore(day.increment()); + return CommandExecutionResult.ok(); + } + + } + + class Just extends SentenceSimple { + + public Just() { + super(SubjectSeparator.this, Verbs.just(), new ComplementBeforeOrAfterOrAtTaskStartOrEnd()); + } + + @Override + public CommandExecutionResult execute(GanttDiagram project, Object subject, Object complement) { + final TaskInstant when = (TaskInstant) complement; + + assert project == subject; + project.addVerticalSeparatorBefore(when.getInstantPrecise()); + return CommandExecutionResult.ok(); + } + + } + +} diff --git a/src/net/sourceforge/plantuml/project/lang/Verbs.java b/src/net/sourceforge/plantuml/project/lang/Verbs.java index cdf377b19..f842aef72 100644 --- a/src/net/sourceforge/plantuml/project/lang/Verbs.java +++ b/src/net/sourceforge/plantuml/project/lang/Verbs.java @@ -155,4 +155,16 @@ public class Verbs { ); } + public static IRegex just() { + return new RegexLeaf("just"); + } + + public static IRegex justBefore() { + return new RegexLeaf("just[%s]*before"); + } + + public static IRegex justAfter() { + return new RegexLeaf("just[%s]*after"); + } + } diff --git a/src/net/sourceforge/plantuml/project/timescale/TimeScaleCompressed.java b/src/net/sourceforge/plantuml/project/timescale/TimeScaleCompressed.java index 77728cdaa..9d1a5bd30 100644 --- a/src/net/sourceforge/plantuml/project/timescale/TimeScaleCompressed.java +++ b/src/net/sourceforge/plantuml/project/timescale/TimeScaleCompressed.java @@ -43,7 +43,7 @@ public class TimeScaleCompressed implements TimeScale { private final TimeScale daily; public TimeScaleCompressed(Day calendar, double scale) { - this.daily = new TimeScaleDaily(scale, calendar, null); + this.daily = new TimeScaleDaily(calendar, scale, null); } public double getStartingPosition(Day instant) { diff --git a/src/net/sourceforge/plantuml/project/timescale/TimeScaleDaily.java b/src/net/sourceforge/plantuml/project/timescale/TimeScaleDaily.java index 4a0a42baf..72315a6fb 100644 --- a/src/net/sourceforge/plantuml/project/timescale/TimeScaleDaily.java +++ b/src/net/sourceforge/plantuml/project/timescale/TimeScaleDaily.java @@ -43,13 +43,12 @@ public final class TimeScaleDaily implements TimeScale { private final TimeScaleWink basic; private final double delta; - public TimeScaleDaily(double scale, Day calendar, Day zeroDay) { + public TimeScaleDaily(Day startingDay, double scale, Day zeroDay) { this.basic = new TimeScaleWink(scale, PrintScale.DAILY); - if (zeroDay == null) { - this.delta = basic.getStartingPosition(calendar); - } else { + if (zeroDay == null) + this.delta = basic.getStartingPosition(startingDay); + else this.delta = basic.getStartingPosition(zeroDay); - } } diff --git a/src/net/sourceforge/plantuml/version/Version.java b/src/net/sourceforge/plantuml/version/Version.java index a9df3c61f..44f0bb47d 100644 --- a/src/net/sourceforge/plantuml/version/Version.java +++ b/src/net/sourceforge/plantuml/version/Version.java @@ -81,7 +81,7 @@ public class Version { } public static int beta() { - final int beta = 10; + final int beta = 11; return beta; }