blob: c498b2dd7c26d2e7a653ccfa8406be6156a8bfe7 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010, 2013 Tasktop Technologies and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Tasktop Technologies - initial API and implementation
*******************************************************************************/
package org.eclipse.mylyn.internal.builds.ui.editor;
import org.eclipse.core.databinding.Binding;
import org.eclipse.core.databinding.UpdateValueStrategy;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.emf.databinding.EMFProperties;
import org.eclipse.emf.databinding.EMFUpdateValueStrategy;
import org.eclipse.emf.databinding.FeaturePath;
import org.eclipse.emf.databinding.IEMFValueProperty;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.jface.action.LegacyActionTools;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.databinding.swt.IWidgetValueProperty;
import org.eclipse.jface.databinding.swt.WidgetProperties;
import org.eclipse.mylyn.builds.core.IBuild;
import org.eclipse.mylyn.builds.core.IBuildElement;
import org.eclipse.mylyn.builds.core.IBuildPlan;
import org.eclipse.mylyn.commons.ui.PlatformUiUtil;
import org.eclipse.mylyn.internal.tasks.ui.editors.EditorUtil;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.forms.AbstractFormPart;
import org.eclipse.ui.forms.IFormColors;
import org.eclipse.ui.forms.IMessageManager;
import org.eclipse.ui.forms.editor.SharedHeaderFormEditor;
import org.eclipse.ui.forms.events.ExpansionAdapter;
import org.eclipse.ui.forms.events.ExpansionEvent;
import org.eclipse.ui.forms.widgets.ExpandableComposite;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;
/**
* @author Steffen Pingel
*/
public abstract class AbstractBuildEditorPart extends AbstractFormPart {
private Control control;
private BuildEditorPage page;
private String partId;
private String partName;
private Section section;
private final int sectionStyle;
int span = 1;
boolean expandVertically;
public AbstractBuildEditorPart() {
this(ExpandableComposite.TITLE_BAR | ExpandableComposite.TWISTIE);
}
public AbstractBuildEditorPart(int sectionStyle) {
this.sectionStyle = sectionStyle;
}
public Control createControl(Composite parent, final FormToolkit toolkit) {
section = createSection(parent, toolkit);
if ((section.getExpansionStyle() & ExpandableComposite.EXPANDED) != 0) {
Control content = createContent(section, toolkit);
section.setClient(content);
} else {
section.addExpansionListener(new ExpansionAdapter() {
@Override
public void expansionStateChanged(ExpansionEvent event) {
if (section.getClient() == null) {
Control content = createContent(section, toolkit);
section.setClient(content);
getPage().reflow();
}
}
});
}
setSection(toolkit, section);
return control;
}
public Control getControl() {
return control;
}
public BuildEditorPage getPage() {
return page;
}
public String getPartId() {
return partId;
}
public String getPartName() {
return partName;
}
public Section getSection() {
return section;
}
public int getSpan() {
return span;
}
public void initialize(BuildEditorPage page) {
this.page = page;
}
/**
* Clients can implement to provide attribute overlay text
*
* @param section
*/
private void createInfoOverlay(Composite composite, Section section, FormToolkit toolkit) {
String text = getInfoOverlayText();
if (text == null) {
return;
}
final Label label = toolkit.createLabel(composite, LegacyActionTools.escapeMnemonics(text));
label.setForeground(toolkit.getColors().getColor(IFormColors.TITLE));
label.setBackground(null);
label.setVisible(!section.isExpanded());
section.addExpansionListener(new ExpansionAdapter() {
@Override
public void expansionStateChanging(ExpansionEvent e) {
label.setVisible(!e.getState());
}
});
}
private IBuild getBuild() {
return getPage().getEditorInput().getBuild();
}
private IBuildPlan getPlan() {
return getPage().getEditorInput().getPlan();
}
protected Binding bind(Text text, Class<? extends IBuildElement> clazz, EStructuralFeature feature) {
return bind(text, clazz, FeaturePath.fromList(feature));
}
protected Binding bind(Text text, Class<? extends IBuildElement> clazz, FeaturePath path) {
IWidgetValueProperty textProp = WidgetProperties.text(SWT.Modify);
IEMFValueProperty property = EMFProperties.value(path);
IObservableValue uiObservable = textProp.observe(text);
IObservableValue modelObservable = property.observe(getInput(clazz));
UpdateValueStrategy modelToTargetStrategy = null;
EStructuralFeature feature = path.getFeaturePath()[path.getFeaturePath().length - 1];
String name = feature.getEType().getName();
if (name.equals("ELong")) {
modelToTargetStrategy = new UpdateValueStrategy();
modelToTargetStrategy.setConverter(new TimestampToStringConverter());
} else {
modelToTargetStrategy = new EMFUpdateValueStrategy();
}
return getPage().getDataBindingContext().bindValue(uiObservable, modelObservable, null, modelToTargetStrategy);
}
protected abstract Control createContent(Composite parent, FormToolkit toolkit);
protected Label createLabel(Composite parent, FormToolkit toolkit, String value) {
Label label = toolkit.createLabel(parent, value);
label.setForeground(toolkit.getColors().getColor(IFormColors.TITLE));
return label;
}
protected Section createSection(Composite parent, FormToolkit toolkit) {
return createSection(parent, toolkit, sectionStyle);
}
protected Section createSection(Composite parent, FormToolkit toolkit, int style) {
Section section = toolkit.createSection(parent, style);
section.setText(getPartName());
return section;
}
protected Text createTextReadOnly(Composite parent, FormToolkit toolkit, String value) {
return createTextReadOnly(parent, toolkit, value, SWT.NONE);
}
protected Text createTextReadOnly(Composite parent, FormToolkit toolkit, String value, int style) {
Text text = new Text(parent, SWT.FLAT | SWT.READ_ONLY | style);
text.setFont(EditorUtil.TEXT_FONT);
text.setData(FormToolkit.KEY_DRAW_BORDER, Boolean.FALSE);
text.setText(value);
toolkit.adapt(text, false, false);
return text;
}
protected void fillToolBar(ToolBarManager toolBarManager) {
}
/**
* Clients can override to show summary information for the part.
*/
protected String getInfoOverlayText() {
return null;
}
@SuppressWarnings("unchecked")
protected <T extends IBuildElement> T getInput(Class<T> clazz) {
if (clazz == IBuildPlan.class) {
return (T) getPlan();
} else if (clazz == IBuild.class) {
return (T) getBuild();
}
return null;
}
protected IMessageManager getMessageManager() {
if (getPage().getEditor() instanceof SharedHeaderFormEditor) {
return ((SharedHeaderFormEditor) getPage().getEditor()).getHeaderForm().getForm().getMessageManager();
} else {
return getManagedForm().getMessageManager();
}
}
protected void inputChanged(IBuildElement oldInput, IBuildElement newInput) {
}
protected void setPartName(String partName) {
this.partName = partName;
}
protected void setSection(FormToolkit toolkit, Section section) {
if (section.getTextClient() == null) {
ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT);
fillToolBar(toolBarManager);
// TODO toolBarManager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
if (toolBarManager.getSize() > 0) {
Composite toolbarComposite = toolkit.createComposite(section);
toolbarComposite.setBackground(null);
RowLayout rowLayout = new RowLayout();
rowLayout.marginLeft = 0;
rowLayout.marginRight = 0;
rowLayout.marginTop = 0;
rowLayout.marginBottom = 0;
rowLayout.center = true;
toolbarComposite.setLayout(rowLayout);
createInfoOverlay(toolbarComposite, section, toolkit);
toolBarManager.createControl(toolbarComposite);
// the toolbar adds spacing, offset to make it consistent with other sections
section.clientVerticalSpacing = 0;
section.descriptionVerticalSpacing = 0;
if (section.getClient() instanceof Composite
&& ((Composite) section.getClient()).getLayout() instanceof GridLayout) {
GridLayout layout = (GridLayout) ((Composite) section.getClient()).getLayout();
layout.marginHeight = 0;
// leave one pixel for borders
layout.marginTop = 1;
layout.marginBottom = 5;
}
section.setTextClient(toolbarComposite);
} else {
// make spacing consistent with sections that have a toolbar
section.clientVerticalSpacing = PlatformUiUtil.getToolbarSectionClientVerticalSpacing();
}
}
setControl(section);
}
void setControl(Control control) {
this.control = control;
}
void setPartId(String partId) {
this.partId = partId;
}
public boolean getExpandVertically() {
return expandVertically;
}
public void setExpandVertically(boolean expandVertically) {
this.expandVertically = expandVertically;
}
}