/*
* Copyright (C) 2006-2016 DLR, Germany
*
* All rights reserved
*
* http://www.rcenvironment.de/
*/
package de.rcenvironment.core.gui.workflow.view.timeline;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
/**
* Represents a Base {@link ScrolledComposite} for a complete List of {@link TimlineComponentRows}.
*
* @author Hendrik Abbenhaus
*/
public class TimelineComponentList extends ScrolledComposite implements ControlListener {
private List<ResizeListener> resizeListener = new ArrayList<ResizeListener>();
private Composite left = null;
private Composite right = null;
private SashForm list = null;
private Map<Label, String> oldTextBuffer = new HashMap<>();
public TimelineComponentList(Composite parent) {
super(parent, SWT.V_SCROLL);
GridData gridData = new GridData();
gridData.horizontalAlignment = GridData.FILL;
gridData.grabExcessHorizontalSpace = true;
gridData.horizontalSpan = 3;
gridData.verticalAlignment = GridData.FILL;
gridData.grabExcessVerticalSpace = true;
this.list = new SashForm(this, SWT.HORIZONTAL);
this.list.setLayoutData(gridData);
this.setContent(this.list);
this.setAlwaysShowScrollBars(true);
this.setExpandVertical(true);
this.setExpandHorizontal(true);
this.addControlListener(this);
this.setShowFocusedControl(true);
FormLayout form = new FormLayout();
this.setLayout(form);
this.left = new Composite(list, SWT.NONE);
this.left.addControlListener(this);
GridLayout gridLayout = new GridLayout(1, false);
left.setLayout(gridLayout);
this.right = new Composite(list, SWT.NONE);
gridLayout = new GridLayout(1, false);
right.setLayout(gridLayout);
this.setWeights(new int[] { 1, 7 });
}
/**
* Sets new Weights.
* @param weights the weights
*/
public void setWeights(int[] weights) {
this.list.setWeights(weights);
//checkLabelabbreviate();
}
public int[] getWeights() {
return this.list.getWeights();
}
// TODO fix label abbreaviation not to use pack() as it can cause problems
// private void checkLabelabbreviate() {
// //on first start the left Composite is not created and has no Size. Then do not short anything!
// if (this.left.getSize().x < 1){
// return;
// }
// for (Object child : this.left.getChildren()) {
// if (child instanceof Label) {
// Label current = (Label) child;
// //if the current Label
// if (!current.getText().equals("")) {
// //set to original text
// if (oldTextBuffer.containsKey(current)){
// current.setText(oldTextBuffer.get(current));
// current.getParent().layout();
// current.pack();
// }
// abbreviateLabel(current, current.getText());
// }
// }
// }
// }
// private void abbreviateLabel(Label label, String labelText) {
// if (label.getSize().x < 1 || label.getSize().y < 1 || labelText.length() < 6){
// return;
// }
// //IconLabelSizeX + NameLabelSizeY + x (multiple border width) > WholeLeftComposite
// if (label.getSize().x + TimelineViewConstants.CANVAS_DEFAULT_HEIGHT_HINT + 10 > this.left.getSize().x){
// //add Name, if there is no entry. Only the first "put" sets the complete name
// if (!oldTextBuffer.containsKey(label)){
// oldTextBuffer.put(label, label.getText());
// }
// String shorterLabelText = "";
// shorterLabelText = StringUtils.abbreviateMiddle(labelText, "...", labelText.length() - 1);
// label.setText(shorterLabelText);
// //set the new size of the label. Otherwise it will always be the shortest String
// label.pack();
// abbreviateLabel(label, shorterLabelText);
// }
// }
/**
* Adds a {@link TimelineComponentRow} to the current List.
* @param row contains the row
*/
public void addComponentRow(TimelineComponentRow row) {
final String tooltipText = row.getName() + " - " + TimelineView.getComponentNameFromId(row.getComponentID(), this);
CLabel nameLabel = new CLabel(this.left, SWT.NONE);
nameLabel.setImage(row.getIcon());
nameLabel.setToolTipText(tooltipText);
nameLabel.setText(row.getName());
nameLabel.setBackground(getBackground());
// remove margins to beautify layout
nameLabel.setMargins(nameLabel.getLeftMargin(), 0, nameLabel.getRightMargin(), 0);
int labelHeight = nameLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT).y;
GridData gridData = new GridData();
gridData.horizontalAlignment = GridData.FILL;
gridData.grabExcessHorizontalSpace = true;
gridData.heightHint = (labelHeight);
TimelineComponentCanvas canvas = new TimelineComponentCanvas(this.right, row.getVisibleStartTime(), row.getVisibleEndTime());
canvas.setLayoutData(gridData);
canvas.setWorkflowEndTime(row.getWorkflowEndTime());
canvas.setActivities(row.getActivities());
}
/**
* Deletes all {@link Label} and {@link TimelineComponentCanvas} elements and clears the oldTextBuffer.
*/
public void clear() {
for (Control current : this.left.getChildren()) {
current.dispose();
if (current instanceof Label) {
current.dispose();
}
}
for (Control current : this.right.getChildren()) {
if (current instanceof TimelineComponentCanvas) {
current.dispose();
}
}
this.left.layout();
this.right.layout();
this.oldTextBuffer.clear();
}
/**
* Sets a new visible time area and carry this over to all {@link TimelineComponentCanvas} .
* @param startTime the current startTime
* @param endTime the current endTime
*/
public void setTimeArea(Date startTime, Date endTime) {
for (Control currentRow : right.getChildren()) {
if (currentRow instanceof TimelineComponentCanvas) {
TimelineComponentCanvas currentCanvas = (TimelineComponentCanvas) currentRow;
currentCanvas.setVisibleTimeArea(startTime, endTime);
}
}
}
/**
* Clears the view an sets an new {@link Array} of {@link TimelineComponentRows} to show.
* @param rows the rows
*/
public void setTimeTableComponentRows(TimelineComponentRow[] rows) {
//first clean all
this.clear();
//if there are no rows, do nothing
if (rows == null || rows.length == 0) {
return;
}
List<TimelineComponentRow> sortedRows = Arrays.asList(rows);
Collections.sort(sortedRows);
for (TimelineComponentRow currentRow : sortedRows) {
addComponentRow(currentRow);
}
this.left.layout();
this.right.layout();
}
@Override
public void controlMoved(ControlEvent arg0) {
}
@Override
public void controlResized(ControlEvent arg0) {
// checkLabelabbreviate();
if (arg0.getSource().equals(this)) {
Rectangle r = this.getClientArea();
this.setMinSize(this.list.computeSize(r.width, SWT.DEFAULT));
} else {
notifyResizeListener();
}
this.redraw();
}
/**
* Adds a {@link ResizeListener} to collection.
* @param a a new listener
*/
public void addResizeListener(ResizeListener a) {
resizeListener.add(a);
}
/**
* Notifies all connected {@link ResizeListener}.
*/
public void notifyResizeListener() {
for (ResizeListener current : resizeListener) {
current.resized();
}
}
/**
* Setting a new background-color in each area.
* @param color the new background-color
*/
@Override
public void setBackground(Color color){
super.setBackground(color);
this.left.setBackground(color);
this.right.setBackground(color);
}
}
/**
* Base for notify via a Listener when resized.
* @author Hendrik Abbenhaus
*/
interface ResizeListener {
void resized();
}