/*
* Licensed Materials - Property of Perforce Software, Inc.
* © Copyright Perforce Software, Inc. 2014, 2021
* © Copyright IBM Corp. 2009, 2014
* © Copyright ILOG 1996, 2009
* All Rights Reserved.
*
* Note to U.S. Government Users Restricted Rights:
* The Software and Documentation were developed at private expense and
* are "Commercial Items" as that term is defined at 48 CFR 2.101,
* consisting of "Commercial Computer Software" and
* "Commercial Computer Software Documentation", as such terms are
* used in 48 CFR 12.212 or 48 CFR 227.7202-1 through 227.7202-4,
* as applicable.
*/
package shared;
import ilog.views.IlvManagerViewInteractor;
import ilog.views.event.InteractorChangedEvent;
import ilog.views.event.InteractorListener;
import ilog.views.gantt.*;
import ilog.views.gantt.action.IlvAction;
import ilog.views.gantt.event.SelectionEvent;
import ilog.views.gantt.event.SelectionListener;
import ilog.views.gantt.graphic.IlvGanttSheet;
import ilog.views.gantt.graphic.interactor.IlvGanttSelectInteractor;
import ilog.views.gantt.graphic.interactor.IlvMakeActivityInteractor;
import ilog.views.gantt.graphic.interactor.IlvMakeConstraintInteractor;
import ilog.views.gantt.model.IlvDefaultGanttModel;
import ilog.views.util.time.IlvCalendarUtil;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.Calendar;
import java.util.Date;
import javax.swing.JComponent;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
/**
* This class groups a set of very useful action inner classes that can be
* applied to a Gantt chart or Schedule chart. These actions can be invoked by a
* menu item, a button in a toolbar, or an accelerator keystroke.
*/
public class GanttCommand {
/**
* Deletes the specified activity or resource from the data model.
*/
public static void removeFromGanttModel(IlvGanttModel model,
IlvHierarchyNode activityOrResource) {
if (!model.contains(activityOrResource)) {
return;
}
if (activityOrResource instanceof IlvResource) {
IlvResource r = (IlvResource) activityOrResource;
if (model.getRootResource() == r) {
model.setRootResource(null);
}
else {
model.removeResource(r);
}
} else if (activityOrResource instanceof IlvActivity) {
IlvActivity a = (IlvActivity) activityOrResource;
if (model.getRootActivity() == a) {
model.setRootActivity(null);
}
else {
model.removeActivity(a);
}
}
}
/**
* Deletes the specified constraint from the data model.
*/
public static void removeFromGanttModel(IlvGanttModel model,
IlvConstraint constraint) {
if (!model.contains(constraint)) {
return;
}
model.removeConstraint(constraint);
}
/**
* Deletes the specified reservation from the data model.
*/
public static void removeFromGanttModel(IlvGanttModel model,
IlvReservation reservation) {
if (!model.contains(reservation)) {
return;
}
model.removeReservation(reservation);
}
/**
* An action that exits the current application.
*/
public static class ExitAction extends IlvAction {
/**
* Creates a new <code>ExitAction</code>.
*/
public ExitAction() {
super("Exit",
null,
KeyStroke.getKeyStroke(KeyEvent.VK_X, KeyEvent.ALT_DOWN_MASK),
"Exit",
"Exits the example.");
}
/**
* Performs the exit action.
*/
Override
public void actionPerformed(ActionEvent event) {
System.exit(0);
}
}
/**
* An action that creates an empty default data model for the specified chart.
*/
public static class NewDataModelAction extends IlvAction {
/**
* The chart.
*/
private IlvHierarchyChart chart;
/**
* Creates a new <code>NewDataModelAction</code>.
*/
public NewDataModelAction(IlvHierarchyChart chart) {
super("New",
null,
KeyStroke.getKeyStroke(KeyEvent.VK_N, KeyEvent.CTRL_DOWN_MASK),
"Create New Project",
"Creates a new project.");
this.chart = chart;
setIcon(GanttCommand.class, "images/new.gif");
}
/**
* Performs the action.
*/
Override
public void actionPerformed(ActionEvent event) {
chart.setGanttModel(new IlvDefaultGanttModel());
}
}
/**
* An action that inserts a new activity into the specified Gantt chart.
*/
public static class InsertActivityAction extends IlvAction {
/**
* The chart.
*/
private IlvGanttChart chart;
/**
* Creates a new <code>InsertActivityAction</code>.
*/
public InsertActivityAction(IlvGanttChart chart) {
super("Insert Activity",
null,
KeyStroke.getKeyStroke(KeyEvent.VK_INSERT, 0),
"Insert Activity",
"Inserts a new activity below the selected activity.");
this.chart = chart;
setIcon(GanttCommand.class, "images/insertrow.gif");
}
/**
* Performs the action.
*/
Override
public void actionPerformed(ActionEvent event) {
IlvGanttModel model = chart.getGanttModel();
if (model == null) {
return;
}
IlvActivityFactory factory = chart.getActivityFactory();
Calendar calendar = Calendar.getInstance();
IlvCalendarUtil.dayFloor(calendar);
Date today = calendar.getTime();
IlvTimeInterval interval =
new IlvTimeInterval(today, IlvDuration.ONE_DAY.multiply(4));
IlvActivity newact = factory.createActivity(interval);
IlvActivity root = model.getRootActivity();
if (root == null) {
model.setRootActivity(newact);
} else {
IlvActivity[] selected = chart.getSelectedActivities();
if (selected.length > 0 && selected[0] != root) {
IlvActivity curact = selected[0];
IlvActivity parent = model.getParentActivity(curact);
int index = model.getParentActivityIndex(curact);
model.addActivity(newact, parent, index + 1);
} else {
int index = model.getChildActivityCount(root);
model.addActivity(newact, root, index);
}
}
chart.deSelectAllRows();
chart.select(newact, true);
makeRowDisplayedLater(chart, newact);
}
}
/**
* An action that inserts a new milestone into the specified Gantt chart.
*/
public static class InsertMilestoneAction extends IlvAction {
/**
* The chart.
*/
private IlvGanttChart chart;
/**
* Creates a new <code>InsertMilestoneAction</code>.
*/
public InsertMilestoneAction(IlvGanttChart chart) {
super("Insert Milestone",
null,
KeyStroke.getKeyStroke(KeyEvent.VK_M, KeyEvent.ALT_DOWN_MASK),
"Insert Milestone",
"Inserts a new milestone below the selected activity.");
this.chart = chart;
setIcon(GanttCommand.class, "images/insertmilestone.gif");
}
/**
* Performs the action.
*/
Override
public void actionPerformed(ActionEvent event) {
IlvGanttModel model = chart.getGanttModel();
if (model == null) {
return;
}
IlvActivityFactory factory = chart.getActivityFactory();
Calendar calendar = Calendar.getInstance();
IlvCalendarUtil.dayFloor(calendar);
Date today = calendar.getTime();
IlvTimeInterval interval = new IlvTimeInterval(today, today);
IlvActivity newact = factory.createActivity(interval);
IlvActivity root = model.getRootActivity();
if (root == null) {
model.setRootActivity(newact);
} else {
IlvActivity[] selected = chart.getSelectedActivities();
if (selected.length > 0 && selected[0] != root) {
IlvActivity curact = selected[0];
IlvActivity parent = model.getParentActivity(curact);
int index = model.getParentActivityIndex(curact);
model.addActivity(newact, parent, index + 1);
} else {
int index = model.getChildActivityCount(root);
model.addActivity(newact, root, index);
}
}
chart.deSelectAllRows();
chart.select(newact, true);
makeRowDisplayedLater(chart, newact);
}
}
/**
* An action that inserts a new resource into the specified Schedule chart.
*/
public static class InsertResourceAction extends IlvAction {
/**
* The chart.
*/
private IlvScheduleChart chart;
/**
* Creates a new <code>InsertResourceAction</code>.
*/
public InsertResourceAction(IlvScheduleChart chart) {
super("Insert Resource",
null,
KeyStroke.getKeyStroke(KeyEvent.VK_INSERT, 0),
"Insert Resource",
"Inserts a new resource below the selected resource.");
this.chart = chart;
setIcon(GanttCommand.class, "images/insertrow.gif");
}
/**
* Performs the action.
*/
Override
public void actionPerformed(ActionEvent event) {
IlvGanttModel model = chart.getGanttModel();
if (model == null) {
return;
}
IlvResourceFactory factory = chart.getResourceFactory();
IlvResource newres = factory.createResource();
IlvResource root = model.getRootResource();
if (root == null) {
model.setRootResource(newres);
} else {
IlvResource[] selected = chart.getSelectedResources();
if (selected.length > 0 && selected[0] != root) {
IlvResource curres = selected[0];
IlvResource parent = model.getParentResource(curres);
int index = model.getParentResourceIndex(curres);
model.addResource(newres, parent, index + 1);
} else {
int index = model.getChildResourceCount(root);
model.addResource(newres, root, index);
}
}
chart.deSelectAllRows();
chart.select(newres, true);
makeRowDisplayedLater(chart, newres);
}
}
/**
* An action that deletes all the selected rows and graphics from the
* specified charts.
*/
public static class DeleteSelectedAction extends IlvAction {
/**
* The array of charts.
*/
private IlvHierarchyChart[] charts;
/**
* Creates a new <code>DeleteSelectedAction</code>.
*
* @param charts The array of charts to which the action applies.
*/
public DeleteSelectedAction(IlvHierarchyChart... charts) {
super("Delete",
null,
KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0),
"Delete",
"");
this.charts = charts;
setIcon(GanttCommand.class, "images/delete.gif");
setLongDescription(computeLongDescription());
SelectionListener selectionListener = new SelectionListener() {
Override
public void selectionChanged(SelectionEvent event) {
computeEnabled();
}
};
for (IlvHierarchyChart chart : charts) {
chart.addSelectionListener(selectionListener);
}
computeEnabled();
}
/**
* Computes the long description of this action.
*/
private String computeLongDescription() {
boolean activities = false;
boolean resources = false;
for (IlvHierarchyChart chart : charts) {
if (chart.getRowType() == IlvGanttConfiguration.ACTIVITY_ROWS) {
activities = true;
} else {
resources = true;
}
}
if (activities && resources) {
return "Deletes the selected activities, resources, constraints, and reservations.";
} else if (activities) {
return "Deletes the selected activities and constraints.";
} else {
return "Deletes the selected resources and reservations.";
}
}
/**
* Computes whether this action should be enabled or not.
*/
private void computeEnabled() {
for (IlvHierarchyChart chart : charts) {
if (chart.getSelectedRows().length > 0
|| chart.getSelectedGraphics().length > 0) {
setEnabled(true);
return;
}
}
setEnabled(false);
}
/**
* Performs the action.
*
* @param event The event that triggers the action.
*/
Override
public void actionPerformed(ActionEvent event) {
for (IlvHierarchyChart chart : charts) {
IlvGanttModel model = chart.getGanttModel();
// First, delete all the selected rows.
IlvHierarchyNode[] selected = chart.getSelectedRows();
for (IlvHierarchyNode row : selected) {
removeFromGanttModel(model, row);
}
// Next, delete the selected reservations.
if (chart instanceof IlvScheduleChart) {
IlvReservation[] reservations =
((IlvScheduleChart) chart).getSelectedReservations();
for (IlvReservation reservation : reservations) {
removeFromGanttModel(model, reservation);
}
}
// Finally, delete the selected constraints.
IlvConstraint[] constraints = chart.getSelectedConstraints();
for (IlvConstraint constraint : constraints) {
removeFromGanttModel(model, constraint);
}
}
}
}
/**
* An action that deletes the selected rows from the specified chart. If the
* chart is a Gantt chart, the action deletes activities. If the chart is a
* Schedule chart, the action deletes resources.
*/
public static class DeleteSelectedRowsAction extends IlvAction {
/**
* The chart.
*/
private IlvHierarchyChart chart;
/**
* Creates a new <code>DeleteSelectedRowsAction</code>.
*/
public DeleteSelectedRowsAction(IlvHierarchyChart chart) {
super(chart instanceof IlvGanttChart
? "Delete Activity"
: "Delete Resource",
null,
KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, KeyEvent.CTRL_DOWN_MASK),
chart instanceof IlvGanttChart
? "Delete Activity"
: "Delete Resource",
chart instanceof IlvGanttChart
? "Deletes the selected activities."
: "Deletes the selected resources.");
this.chart = chart;
setIcon(GanttCommand.class, "images/deleterow.gif");
chart.addSelectionListener(new SelectionListener()
{
Override
public void selectionChanged(SelectionEvent event) {
computeEnabled();
}
});
computeEnabled();
}
/**
* Computes whether this action should be enabled or not.
*/
private void computeEnabled() {
setEnabled(chart.getSelectedRows().length > 0);
}
/**
* Performs the action.
*/
Override
public void actionPerformed(ActionEvent event) {
IlvGanttModel model = chart.getGanttModel();
IlvHierarchyNode[] selected = chart.getSelectedRows();
for (IlvHierarchyNode row : selected) {
removeFromGanttModel(model, row);
}
}
}
/**
* An action that deletes the selected constraints from the specified
* chart.
*/
public static class DeleteSelectedConstraintsAction extends IlvAction {
/**
* The chart.
*/
private IlvHierarchyChart chart;
/**
* Creates a new <code>DeleteSelectedConstraintsAction</code>.
*/
public DeleteSelectedConstraintsAction(IlvHierarchyChart chart) {
super("Delete Constraint",
null,
KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, KeyEvent.SHIFT_DOWN_MASK),
"Delete Constraint",
"Deletes the selected constraints.");
this.chart = chart;
setIcon(GanttCommand.class, "images/deleteconstraint.gif");
chart.addSelectionListener(new SelectionListener()
{
Override
public void selectionChanged(SelectionEvent event) {
computeEnabled();
}
});
computeEnabled();
}
/**
* Computes whether this action should be enabled or not.
*/
private void computeEnabled() {
setEnabled(chart.getSelectedConstraints().length > 0);
}
/**
* Performs the action.
*/
Override
public void actionPerformed(ActionEvent event) {
IlvGanttModel model = chart.getGanttModel();
IlvConstraint[] constraints = chart.getSelectedConstraints();
for (IlvConstraint constraint : constraints) {
removeFromGanttModel(model, constraint);
}
}
}
/**
* An action that deletes the selected reservations from the specified
* Schedule chart.
*/
public static class DeleteSelectedReservationsAction extends IlvAction {
/**
* The chart.
*/
private IlvScheduleChart chart;
/**
* Creates a new <code>DeleteSelectedReservationsAction</code>.
*/
public DeleteSelectedReservationsAction(IlvScheduleChart chart) {
super("Delete Reservation",
null,
KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, KeyEvent.SHIFT_DOWN_MASK),
"Delete Reservation",
"Deletes the selected reservations.");
this.chart = chart;
setIcon(GanttCommand.class, "images/deleteactivity.gif");
chart.addSelectionListener(new SelectionListener()
{
Override
public void selectionChanged(SelectionEvent event) {
computeEnabled();
}
});
computeEnabled();
}
/**
* Computes whether this action should be enabled or not.
*/
private void computeEnabled() {
setEnabled(chart.getSelectedReservations().length > 0);
}
/**
* Performs the action.
*/
Override
public void actionPerformed(ActionEvent event) {
IlvGanttModel model = chart.getGanttModel();
IlvReservation[] reservations = chart.getSelectedReservations();
for (IlvReservation reservation : reservations) {
removeFromGanttModel(model, reservation);
}
}
}
/**
* An action that installs the constraint creation interactor on the specified
* chart.
*/
public static class MakeConstraintAction extends IlvAction {
/**
* The chart.
*/
private IlvHierarchyChart chart;
/**
* The ESC key.
*/
private KeyStroke escKey;
/**
* The ESC key action.
*/
private ActionListener escAction;
/**
* Creates a new <code>MakeConstraintAction</code>.
*/
public MakeConstraintAction(IlvHierarchyChart chart) {
super("Create Constraint",
null,
KeyStroke.getKeyStroke(KeyEvent.VK_C, KeyEvent.ALT_DOWN_MASK),
"Create Constraint",
"Creates a new constraint using the mouse.");
this.chart = chart;
setIcon(GanttCommand.class, "images/constraint.gif");
escKey = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
// Define the ESC action that will abort the current make-constraint
// interactor. This supplements the built-in ESC key handling of the
// interactor itself, since the interactor only receives keystrokes
// when the Gantt sheet has the focus. This action will be registered
// as an application-wide accelerator.
escAction = new ActionListener() {
Override
public void actionPerformed(ActionEvent actionEvent) {
IlvHierarchyChart chart = MakeConstraintAction.this.chart;
IlvGanttSheet ganttSheet = chart.getGanttSheet();
IlvManagerViewInteractor current = ganttSheet.getInteractor();
if (current instanceof IlvMakeConstraintInteractor) {
((IlvMakeConstraintInteractor) current).abort();
}
}
};
// Listen for changes in the Gantt sheet's current interactor. When
// a make-constraint interactor is set, we register the ESC action
// application-wide. When a make-constraint interactor is unset, we
// unregister the ESC action.
chart.getGanttSheet().addInteractorListener(new InteractorListener() {
Override
public void interactorChanged(InteractorChangedEvent event) {
IlvHierarchyChart chart = MakeConstraintAction.this.chart;
if (event.getOldValue()instanceof IlvMakeConstraintInteractor) {
chart.unregisterKeyboardAction(escKey);
}
if (event.getNewValue()instanceof IlvMakeConstraintInteractor) {
chart.registerKeyboardAction(escAction,
escKey,
JComponent.WHEN_IN_FOCUSED_WINDOW);
}
}
});
}
/**
* Performs the action by setting the make-constraint interactor onto
* the Gantt sheet.
*/
Override
public void actionPerformed(ActionEvent event) {
IlvGanttSheet ganttSheet = chart.getGanttSheet();
IlvManagerViewInteractor current = ganttSheet.getInteractor();
if (current instanceof IlvMakeConstraintInteractor) {
return;
}
IlvMakeConstraintInteractor lnkinter = new IlvMakeConstraintInteractor();
ganttSheet.pushInteractor(lnkinter);
}
}
/**
* An action that installs the activity creation interactor on the specified
* chart.
*/
public static class MakeActivityAction extends IlvAction {
/**
* The chart.
*/
private IlvHierarchyChart chart;
/**
* Creates a new <code>MakeActivityAction</code>.
*/
public MakeActivityAction(IlvHierarchyChart chart) {
super(chart instanceof IlvGanttChart
? "Create Activity"
: "Create Reservation",
null,
chart instanceof IlvGanttChart
? KeyStroke.getKeyStroke(KeyEvent.VK_A, KeyEvent.ALT_DOWN_MASK)
: KeyStroke.getKeyStroke(KeyEvent.VK_R, KeyEvent.ALT_DOWN_MASK),
chart instanceof IlvGanttChart
? "Create Activity"
: "Create Reservation",
chart instanceof IlvGanttChart
? "Creates a new activity using the mouse."
: "Creates a new reservation using the mouse.");
this.chart = chart;
setIcon(GanttCommand.class, "images/newactivity.gif");
}
/**
* Performs the action.
*/
Override
public void actionPerformed(ActionEvent event) {
IlvManagerViewInteractor current = chart.getGanttSheet().getInteractor();
if (current instanceof IlvMakeActivityInteractor) {
return;
}
IlvMakeActivityInteractor inter = new IlvMakeActivityInteractor();
if (current instanceof IlvGanttSelectInteractor) {
inter.
setGhostMode(!((IlvGanttSelectInteractor) current).isOpaqueMove());
}
chart.getGanttSheet().pushInteractor(inter);
}
}
/**
* An action that outdents the first selected row of the specified chart to a
* higher hierarchy level. If the chart is a Gantt chart, the action outdents
* activities. If the chart is a Schedule chart, the action outdents
* resources.
*/
public static class RowOutdentAction extends IlvAction {
/**
* The chart.
*/
private IlvHierarchyChart chart;
/**
* Creates a new <code>RowOutdentAction</code>.
*/
public RowOutdentAction(IlvHierarchyChart chart) {
super(chart instanceof IlvGanttChart
? "Outdent Activity"
: "Outdent Resource",
null,
KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, KeyEvent.CTRL_DOWN_MASK),
chart instanceof IlvGanttChart
? "Outdent Activity"
: "Outdent Resource",
chart instanceof IlvGanttChart
? "Outdents the selected activity."
: "Outdents the selected resource.");
this.chart = chart;
setIcon(GanttCommand.class, "images/outdent.gif");
chart.addSelectionListener(new SelectionListener()
{
Override
public void selectionChanged(SelectionEvent event) {
computeEnabled();
}
});
computeEnabled();
}
/**
* Computes whether this action should be enabled or not.
*/
private void computeEnabled() {
setEnabled(chart.getSelectedRows().length > 0);
}
/**
* Performs the action.
*/
Override
public void actionPerformed(ActionEvent event) {
IlvHierarchyNode[] selectedRows = chart.getSelectedRows();
if (selectedRows.length == 0) {
return;
}
IlvHierarchyNode row = selectedRows[0];
IlvGanttModelUtil.promote(chart.getGanttModel(), row);
makeRowDisplayedLater(chart, row);
}
}
/**
* An action that indents the first selected row of the specified chart to a
* lower hierarchy level. If the chart is a Gantt chart, the action indents
* activities. If the chart is a Schedule chart, the action indents resources.
*/
public static class RowIndentAction extends IlvAction {
/**
* The chart.
*/
private IlvHierarchyChart chart;
/**
* Creates a new <code>RowIndentAction</code>.
*/
public RowIndentAction(IlvHierarchyChart chart) {
super(chart instanceof IlvGanttChart
? "Indent Activity"
: "Indent Resource",
null,
KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, KeyEvent.CTRL_DOWN_MASK),
chart instanceof IlvGanttChart
? "Indent Activity"
: "Indent Resource",
chart instanceof IlvGanttChart
? "Indents the selected activity."
: "Indents the selected resource.");
this.chart = chart;
setIcon(GanttCommand.class, "images/indent.gif");
chart.addSelectionListener(new SelectionListener()
{
Override
public void selectionChanged(SelectionEvent event) {
computeEnabled();
}
});
computeEnabled();
}
/**
* Computes whether this action should be enabled or not.
*/
private void computeEnabled() {
setEnabled(chart.getSelectedRows().length > 0);
}
/**
* Performs the action.
*/
Override
public void actionPerformed(ActionEvent event) {
IlvHierarchyNode[] selectedRows = chart.getSelectedRows();
if (selectedRows.length == 0) {
return;
}
IlvGanttModel model = chart.getGanttModel();
IlvHierarchyNode row = selectedRows[0];
IlvGanttModelUtil.demote(model, row);
IlvHierarchyNode newParent = model.getParent(row);
if (newParent != null && !chart.isRowExpanded(newParent)) {
chart.expandRow(newParent);
chart.selectRow(row, true);
}
makeRowDisplayedLater(chart, row);
}
}
/**
* An action that moves the first selected row of the specified chart upwards.
* If the chart is a Gantt chart, the action moves activities. If the chart is
* a Schedule chart, the action moves resources.
*/
public static class RowUpAction extends IlvAction {
/**
* The chart.
*/
private IlvHierarchyChart chart;
/**
* Creates a new <code>RowUpAction</code>.
*/
public RowUpAction(IlvHierarchyChart chart) {
super(chart instanceof IlvGanttChart
? "Move Activity Up"
: "Move Resource Up",
null,
KeyStroke.getKeyStroke(KeyEvent.VK_UP, KeyEvent.CTRL_DOWN_MASK),
chart instanceof IlvGanttChart
? "Move Activity Up"
: "Move Resource Up",
chart instanceof IlvGanttChart
? "Moves the selected activity up."
: "Moves the selected resource up.");
this.chart = chart;
setIcon(GanttCommand.class, "images/up.gif");
chart.addSelectionListener(new SelectionListener()
{
Override
public void selectionChanged(SelectionEvent event) {
computeEnabled();
}
});
computeEnabled();
}
/**
* Computes whether this action should be enabled or not.
*/
private void computeEnabled() {
setEnabled(chart.getSelectedRows().length > 0);
}
/**
* Performs the action.
*/
Override
public void actionPerformed(ActionEvent event) {
IlvHierarchyNode[] selectedRows = chart.getSelectedRows();
if (selectedRows.length == 0) {
return;
}
IlvGanttModel model = chart.getGanttModel();
IlvHierarchyNode row = selectedRows[0];
IlvHierarchyNode parent = model.getParent(row);
if (parent == null) {
return;
}
int index = model.getParentIndex(row);
if (index == 0) {
return;
}
if (row instanceof IlvActivity) {
model.moveActivity((IlvActivity) row, (IlvActivity) parent, index - 1);
}
else {
model.moveResource((IlvResource) row, (IlvResource) parent, index - 1);
}
makeRowDisplayedLater(chart, row);
}
}
/**
* An action that moves the first selected row of the specified chart
* downwards.
* If the chart is a Gantt chart, the action moves activities. If the chart is
* a Schedule chart, the action moves resources.
*/
public static class RowDownAction extends IlvAction {
/**
* The chart.
*/
private IlvHierarchyChart chart;
/**
* Creates a new <code>RowDownAction</code>.
*/
public RowDownAction(IlvHierarchyChart chart) {
super(chart instanceof IlvGanttChart
? "Move Activity Down"
: "Move Resource Down",
null,
KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, KeyEvent.CTRL_DOWN_MASK),
chart instanceof IlvGanttChart
? "Move Activity Down"
: "Move Resource Down",
chart instanceof IlvGanttChart
? "Moves the selected activity down."
: "Moves the selected resource down.");
this.chart = chart;
setIcon(GanttCommand.class, "images/down.gif");
chart.addSelectionListener(new SelectionListener()
{
Override
public void selectionChanged(SelectionEvent event) {
computeEnabled();
}
});
computeEnabled();
}
/**
* Computes whether this action should be enabled or not.
*/
private void computeEnabled() {
setEnabled(chart.getSelectedRows().length > 0);
}
/**
* Performs the action.
*/
Override
public void actionPerformed(ActionEvent event) {
IlvHierarchyNode[] selectedRows = chart.getSelectedRows();
if (selectedRows.length == 0) {
return;
}
IlvGanttModel model = chart.getGanttModel();
IlvHierarchyNode row = selectedRows[0];
IlvHierarchyNode parent = model.getParent(row);
if (parent == null) {
return;
}
int index = model.getParentIndex(row);
if (index == model.getChildCount(parent) - 1) {
return;
}
if (row instanceof IlvActivity) {
model.moveActivity((IlvActivity) row, (IlvActivity) parent, index + 1);
}
else {
model.moveResource((IlvResource) row, (IlvResource) parent, index + 1);
}
makeRowDisplayedLater(chart, row);
}
}
/**
* An action that toggles the expansion of the selected rows in the
* specified charts.
*/
public static class RowExpandCollapseAction extends IlvAction {
/**
* The array of charts.
*/
private IlvHierarchyChart[] charts;
/**
* Creates a new <code>RowExpandCollapseAction</code>.
*
* @param charts The array of charts to which the action applies.
*/
public RowExpandCollapseAction(IlvHierarchyChart... charts) {
super("",
null,
KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, KeyEvent.CTRL_DOWN_MASK),
"",
"");
this.charts = charts;
setIcon(GanttCommand.class, "images/plusminus.gif");
setName(computeShortDescription());
setShortDescription(computeShortDescription());
setLongDescription(computeLongDescription());
SelectionListener selectionListener = new SelectionListener() {
Override
public void selectionChanged(SelectionEvent event) {
computeEnabled(event);
}
};
for (IlvHierarchyChart chart : charts) {
chart.addSelectionListener(selectionListener);
}
computeEnabled(null);
}
/**
* Computes the short description of this action.
*/
private String computeShortDescription() {
boolean activities = false;
boolean resources = false;
for (IlvHierarchyChart chart : charts) {
if (chart.getRowType() == IlvGanttConfiguration.ACTIVITY_ROWS) {
activities = true;
} else {
resources = true;
}
}
if (activities && resources) {
return "Expand/Collapse Activities and Resources";
} else if (activities) {
return "Expand/Collapse Activities";
} else {
return "Expand/Collapse Resources";
}
}
/**
* Computes the long description of this action.
*/
private String computeLongDescription() {
boolean activities = false;
boolean resources = false;
for (IlvHierarchyChart chart : charts) {
if (chart.getRowType() == IlvGanttConfiguration.ACTIVITY_ROWS) {
activities = true;
} else {
resources = true;
}
}
if (activities && resources) {
return "Toggles expansion of the selected activities and resources.";
} else if (activities) {
return "Toggles expansion of the selected activities.";
} else {
return "Toggles expansion of the selected resources.";
}
}
/**
* Computes whether this action should be enabled or not for the specified chart.
* This method returns <code>null</code> if the event cannot be applied to the
* chart.
*/
private Boolean computeEnabled(IlvHierarchyChart chart, SelectionEvent event) {
int chartType = chart.getRowType();
if (event != null) {
if (event.isAdjusting()) {
return null;
}
Object eventSource = event.getSource();
if (chartType == IlvGanttConfiguration.ACTIVITY_ROWS) {
if (!(eventSource instanceof IlvActivity)) {
return null;
}
} else if (chartType == IlvGanttConfiguration.RESOURCE_ROWS) {
if (!(eventSource instanceof IlvResource)) {
return null;
}
}
}
IlvGanttModel model = chart.getGanttModel();
IlvHierarchyNode[] selectedRows = chart.getSelectedRows();
for (IlvHierarchyNode row : selectedRows) {
if (IlvGanttModelUtil.hasChildren(model, row)) {
return true;
}
}
return false;
}
/**
* Computes whether this action should be enabled or not.
*/
private void computeEnabled(SelectionEvent event) {
Boolean enable = null;
for (IlvHierarchyChart chart : charts) {
Boolean chartResult = computeEnabled(chart, event);
if (chartResult != null) {
if (enable == null) {
enable = chartResult;
} else {
enable = enable || chartResult;
}
}
}
if (enable != null) {
setEnabled(enable);
}
}
/**
* Performs the action.
*/
Override
public void actionPerformed(ActionEvent event) {
Boolean expanded = null;
for (IlvHierarchyChart chart : charts) {
IlvGanttModel model = chart.getGanttModel();
IlvHierarchyNode[] selectedRows = chart.getSelectedRows();
for (IlvHierarchyNode row : selectedRows) {
if (IlvGanttModelUtil.hasChildren(model, row)) {
if (expanded == null) {
expanded = chart.isRowExpanded(row);
}
if (expanded) {
chart.collapseRow(row);
} else {
chart.expandRow(row);
}
}
}
}
}
}
/**
* An action that changes the height of the rows in the specified charts.
*/
public static class RowHeightAction extends IlvAction {
/**
* The array of charts.
*/
private IlvHierarchyChart[] charts;
/**
* The amount to change the row height.
*/
private int delta;
/**
* The minimum row height.
*/
private int minRowHeight = 12;
/**
* The maximum row height.
*/
private int maxRowHeight = 50;
/**
* Creates a new <code>RowHeightAction</code>.
*
* @param delta The number of pixels to change the height of the chart rows by.
* @param charts The array of charts to which the action applies.
*/
public RowHeightAction(int delta, IlvHierarchyChart... charts) {
super((delta >= 0)
? "Increase " + delta + " Pixels"
: "Decrease " + (-delta) + " Pixels",
null,
null,
(delta >= 0)
? "Increase Row Height " + delta + " Pixels"
: "Decrease Row Height " + (-delta) + " Pixels",
(delta >= 0)
? "Increases the row height by " + delta + " pixels."
: "Decreases the row height by " + (-delta) + " pixels.");
this.charts = charts;
this.delta = delta;
}
/**
* Returns the amount that the row height will be changed.
*/
public int getDelta() {
return delta;
}
/**
* Returns the minimum row height.
*/
public int getMinRowHeight() {
return minRowHeight;
}
/**
* Sets the minimum row height.
*/
public void setMinRowHeight(int min) {
minRowHeight = min;
}
/**
* Returns the maximum row height.
*/
public int getMaxRowHeight() {
return maxRowHeight;
}
/**
* Sets the maximum row height.
*/
public void setMaxRowHeight(int max) {
maxRowHeight = max;
}
/**
* Performs the action.
*/
Override
public void actionPerformed(ActionEvent event) {
for (IlvHierarchyChart chart : charts) {
int height = chart.getRowHeight();
height += delta;
height = Math.max(height, minRowHeight);
height = Math.min(height, maxRowHeight);
chart.setRowHeight(height);
}
}
}
/**
* Ensures that the specified <i>row</i> is displayed, by calling the chart's
* <code>makeRowDisplayed()</code> method on the Swing event queue. It is
* necessary to use this technique and delay execution of the chart's
* <code>makeRowDisplayed()</code> method when row visibilities have
* just been modified. This is because the chart also updates its internal
* knowledge of which rows are within the display area on the Swing event
* queue.
*/
public static void makeRowDisplayedLater(final IlvHierarchyChart chart,
final IlvHierarchyNode row) {
SwingUtilities.invokeLater(new Runnable() {
Override
public void run() {
chart.makeRowDisplayed(row);
}
});
}
}