blob: 37f129fdefc28a10a45e87fccf5ade94aaf4eb41 [file] [log] [blame]
//------------------------------------------------------------------------------
// Copyright (c) 2005, 2007 IBM Corporation 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:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.authoring.ui.properties;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
import org.eclipse.epf.authoring.ui.providers.VariabilityElementLabelProvider;
import org.eclipse.epf.library.edit.IConfigurationApplicator;
import org.eclipse.epf.library.edit.Providers;
import org.eclipse.epf.library.edit.TngAdapterFactory;
import org.eclipse.epf.library.edit.command.IActionManager;
import org.eclipse.epf.library.edit.util.DescriptorPropUtil;
import org.eclipse.epf.library.edit.util.ProcessUtil;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.uma.Descriptor;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.TaskDescriptor;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableFontProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Table;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.ListSelectionDialog;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
/**
* The task descriptor - step section
*
* @author Shilpa Toraskar
* @since 1.0
*
*/
public class TaskDescriptorStepSection extends AbstractSection {
private TaskDescriptor element;
private IActionManager actionMgr;
private FormToolkit toolkit;
private Button ctrl_add, ctrl_remove, ctrl_up, ctrl_down;
private Table ctrl_selected;
private TableViewer viewer;
// private Text ctrl_brief_desc;
private Image titleImage;
/* (non-Javadoc)
* @see org.eclipse.epf.authoring.ui.properties.AbstractSection#createControls(org.eclipse.swt.widgets.Composite, org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage)
*/
public void createControls(Composite parent,
TabbedPropertySheetPage tabbedPropertySheetPage) {
super.createControls(parent, tabbedPropertySheetPage);
init();
parent.setLayout(new GridLayout());
parent.setLayoutData(new GridData(GridData.FILL_BOTH));
// create steps section
createStepSection(parent);
addListeners();
}
/**
* Initialize
*
*/
private void init() {
// get activity object
element = (TaskDescriptor) getElement();
// get toolkit
toolkit = getWidgetFactory();
// get action manager
actionMgr = EPFPropertySheetPage.getActionManager();
}
/* (non-Javadoc)
* @see org.eclipse.ui.views.properties.tabbed.AbstractPropertySection#refresh()
*/
public void refresh() {
try {
if (getElement() instanceof TaskDescriptor) {
element = (TaskDescriptor) getElement();
// hide/refresh controls
updateControls();
if (isSyncFree()) {
syncFreeUpdateControls();
}
initContentProvider();
initLabelProvider();
viewer.refresh();
}
} catch (Exception ex) {
logger.logError("Error refreshing TaskDescriptor step section" + element, ex); //$NON-NLS-1$
}
}
/* (non-Javadoc)
* @see org.eclipse.epf.authoring.ui.properties.AbstractSection#dispose()
*/
public void dispose() {
super.dispose();
}
/**
* Update controls based on editable flag. Controls will be either editable
* or read-only after updating this.
*/
public void updateControls() {
ctrl_add.setEnabled(editable);
if (element.getTask() == null)
ctrl_add.setEnabled(false);
else {
List steps = getSteps();
if (steps != null && steps.size() > 0)
ctrl_add.setEnabled(true);
else
ctrl_add.setEnabled(false);
}
IStructuredSelection selection = (IStructuredSelection) viewer
.getSelection();
if (selection.size() > 0 && editable) {
ctrl_remove.setEnabled(editable);
ctrl_up.setEnabled(editable);
ctrl_down.setEnabled(editable);
} else {
ctrl_remove.setEnabled(false);
ctrl_up.setEnabled(false);
ctrl_down.setEnabled(false);
}
}
/**
* Create Step section on the given composite
* @param composite
*/
private void createStepSection(Composite composite) {
// create step section
String sectionDesc = PropertiesResources.TaskDescriptor_stepInformationDescription;
Section stepSection = FormUI
.createSection(
toolkit,
composite,
PropertiesResources.TaskDescriptor_stepInformationTitle,
sectionDesc);
// create step composite
Composite stepComposite = FormUI.createComposite(toolkit, stepSection,
2, false);
// create table composite
Composite pane1 = FormUI.createComposite(toolkit, stepComposite,
GridData.FILL_BOTH);
FormUI.createLabel(toolkit, pane1, PropertiesResources.TaskDescriptor_Selected_Steps);
ctrl_selected = FormUI.createTable(toolkit, pane1);
viewer = new TableViewer(ctrl_selected);
initContentProvider();
initLabelProvider();
viewer.setInput(element);
// create button composite
Composite pane2 = FormUI.createComposite(toolkit, stepComposite,
GridData.VERTICAL_ALIGN_CENTER
| GridData.HORIZONTAL_ALIGN_CENTER);
// create buttons
ctrl_add = FormUI.createButton(toolkit, pane2, PropertiesResources.Process_Add);
ctrl_add.setEnabled(false);
ctrl_remove = FormUI.createButton(toolkit, pane2, PropertiesResources.Process_Remove);
ctrl_remove.setEnabled(false);
ctrl_up = FormUI.createButton(toolkit, pane2, PropertiesResources.Process_Up);
ctrl_down = FormUI.createButton(toolkit, pane2, PropertiesResources.Process_Down);
if (element.getTask() != null) {
List steps = getSteps();
if (steps != null && steps.size() > 0) {
ctrl_add.setEnabled(true);
}
}
// create brief description
// int heightHint = 40;
// int horizontalSpan = 2;
// Label label = FormUI.createLabel(toolkit, stepComposite,
// PropertiesResources.getString("Process.briefDescription"),
// heightHint);
// ctrl_brief_desc = FormUI.createText(toolkit, stepComposite,
// heightHint, heightHint);
// ctrl_brief_desc.setEditable(false);
//
toolkit.paintBordersFor(stepComposite);
toolkit.paintBordersFor(pane1);
}
/**
* Add listeners
*/
private void addListeners() {
// Add focus listener on primary tasks list
ctrl_selected.addFocusListener(new FocusAdapter() {
public void focusGained(FocusEvent e) {
IStructuredSelection selection = (IStructuredSelection) viewer
.getSelection();
if ((selection.size() > 0) && editable) {
ctrl_remove.setEnabled(editable);
ctrl_up.setEnabled(editable);
ctrl_down.setEnabled(editable);
}
if (isSyncFree()) {
syncFreeUpdateControls();
}
}
});
viewer.addSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
IStructuredSelection selection = (IStructuredSelection) viewer
.getSelection();
if ((selection.size() > 0) && editable) {
ctrl_remove.setEnabled(true);
if (viewer.getTable().getSelectionIndex() > 0
&& selection.size() == 1) {
ctrl_up.setEnabled(true);
} else
ctrl_up.setEnabled(false);
if (viewer.getTable().getSelectionIndex() < viewer
.getTable().getItemCount() - 1
&& selection.size() == 1) {
ctrl_down.setEnabled(true);
} else
ctrl_down.setEnabled(false);
}
if (selection.size() == 1) {
String desc = ((MethodElement) selection.getFirstElement())
.getBriefDescription();
if (desc == null) {
desc = ""; //$NON-NLS-1$
}
// ctrl_brief_desc.setText(desc);
} else if (selection.size() > 1) {
// ctrl_brief_desc.setText(PropertiesResources.getString("Process.MultipleSelection")
// + " - " + selection.size());
}
if (isSyncFree()) {
syncFreeUpdateControls();
}
}
});
ctrl_add.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
if (isSyncFree()) {
IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
addSteps(selection.toArray());
viewer.refresh();
syncFreeUpdateControls();
return;
}
IStructuredContentProvider stepContentProvider = new AdapterFactoryContentProvider(
TngAdapterFactory.INSTANCE
.getNavigatorView_ComposedAdapterFactory()) {
public Object[] getElements(Object object) {
return getSteps().toArray();
// // get all steps
// IConfigurationApplicator configApplicator = Providers
// .getConfigurationApplicator();
// MethodConfiguration config = TngUtil.getOwningProcess(
// element).getDefaultContext();
// List steps = (List) configApplicator.getReference(
// element.getTask(), UmaPackage.eINSTANCE
// .getTask_Steps(), config);
//
// // remove already existing steps
// steps.removeAll(element.getSelectedSteps());
// return steps.toArray();
}
};
ILabelProvider stepLabelProvider = new VariabilityElementLabelProvider(
TngAdapterFactory.INSTANCE
.getNavigatorView_ComposedAdapterFactory()) {
public boolean isExternal(Object obj) {
boolean flag = !element.getTask().getPresentation()
.getSections().contains(obj);
return flag;
}
};
ListSelectionDialog dlg = new ListSelectionDialog(PlatformUI
.getWorkbench().getActiveWorkbenchWindow().getShell(),
element.getTask(), stepContentProvider,
stepLabelProvider, PropertiesResources.TaskDescriptor_StepDialogMessage);
titleImage = Display.getCurrent().getActiveShell().getImage();
ListSelectionDialog.setDefaultImage(titleImage);
dlg.setTitle(PropertiesResources.TaskDescriptor_StepDialogTitle);
dlg.setBlockOnOpen(true);
dlg.open();
addSteps(dlg.getResult());
// enable/disable add button
List steps = getSteps();
if (steps != null && steps.size() > 0)
ctrl_add.setEnabled(true);
else
ctrl_add.setEnabled(false);
viewer.refresh();
}
});
ctrl_remove.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
IStructuredSelection selection = (IStructuredSelection) viewer
.getSelection();
if (selection.size() > 0) {
// update the model
ArrayList rmItems = new ArrayList();
rmItems.addAll(selection.toList());
removeSteps(rmItems);
viewer.refresh();
// clear the selection
viewer.setSelection(null, true);
// ctrl_brief_desc.setText("");
}
// ctrl_remove.setEnabled(false);
// enable/disable add button
List steps = getSteps();
if (steps != null && steps.size() > 0)
ctrl_add.setEnabled(true);
else
ctrl_add.setEnabled(false);
if (isSyncFree()) {
syncFreeUpdateControls();
}
}
});
ctrl_up.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
ArrayList steps = new ArrayList();
IStructuredSelection selection = (IStructuredSelection) viewer
.getSelection();
if (selection.size() > 0) {
ArrayList items = new ArrayList();
items.addAll(selection.toList());
BasicEList stepList = (BasicEList) element
.getSelectedSteps();
for (Iterator it = items.iterator(); it.hasNext();) {
Object object = it.next();
int index = stepList.indexOf(object);
if (index > 0)
stepList.move(index - 1, object);
}
steps.addAll(stepList);
// TODO - write a command.
// activate dirty flag
actionMgr.doAction(IActionManager.REMOVE_MANY, element,
UmaPackage.eINSTANCE
.getTaskDescriptor_SelectedSteps(),
stepList, -1);
actionMgr.doAction(IActionManager.ADD_MANY, element,
UmaPackage.eINSTANCE
.getTaskDescriptor_SelectedSteps(), steps,
-1);
viewer.refresh();
}
if (viewer.getTable().getSelectionIndex() > 0 && editable)
ctrl_up.setEnabled(true);
else
ctrl_up.setEnabled(false);
if (viewer.getTable().getSelectionIndex() < viewer.getTable()
.getItemCount() - 1
&& editable)
ctrl_down.setEnabled(true);
else
ctrl_down.setEnabled(false);
}
});
ctrl_down.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
ArrayList steps = new ArrayList();
IStructuredSelection selection = (IStructuredSelection) viewer
.getSelection();
if (selection.size() > 0) {
ArrayList items = new ArrayList();
items.addAll(selection.toList());
BasicEList stepList = (BasicEList) element
.getSelectedSteps();
for (Iterator it = items.iterator(); it.hasNext();) {
Object object = it.next();
int index = stepList.indexOf(object);
if (index < stepList.size() - 1)
stepList.move(index + items.size(), object);
}
steps.addAll(stepList);
// TODO - write a cmmand. Hacking it for now to activate
// dirty flag
actionMgr.doAction(IActionManager.REMOVE_MANY, element,
UmaPackage.eINSTANCE
.getTaskDescriptor_SelectedSteps(),
stepList, -1);
actionMgr.doAction(IActionManager.ADD_MANY, element,
UmaPackage.eINSTANCE
.getTaskDescriptor_SelectedSteps(), steps,
-1);
viewer.refresh();
}
if (viewer.getTable().getSelectionIndex() > 0 && editable)
ctrl_up.setEnabled(true);
else
ctrl_up.setEnabled(false);
if (viewer.getTable().getSelectionIndex() < viewer.getTable()
.getItemCount() - 1
&& editable)
ctrl_down.setEnabled(true);
else
ctrl_down.setEnabled(false);
}
});
}
/**
* Assign Steps to task descriptor
* @param addItems
* List of steps
*/
private void addSteps(Object[] addItems) {
// update the model
if (addItems != null) {
for (int i = 0; i < addItems.length; i++) {
org.eclipse.epf.uma.Section item = (org.eclipse.epf.uma.Section) addItems[i];
actionMgr.doAction(IActionManager.ADD, element,
UmaPackage.eINSTANCE.getTaskDescriptor_SelectedSteps(),
item, -1);
if (isSyncFree()) {
actionMgr.doAction(IActionManager.REMOVE, element,
UmaPackage.eINSTANCE.getTaskDescriptor_SelectedStepsExclude(),
item, -1);
DescriptorPropUtil propUtil = DescriptorPropUtil
.getDesciptorPropUtil(actionMgr);
TaskDescriptor greenParent = (TaskDescriptor) propUtil
.getGreenParentDescriptor(element);
if (greenParent != null) {
EReference eRef = UmaPackage.eINSTANCE
.getTaskDescriptor_SelectedStepsExclude();
List<org.eclipse.epf.uma.Section> parentExecludeList = greenParent
.getSelectedStepsExclude();
propUtil.removeGreenRefDelta(element, item, eRef, true);
if (parentExecludeList != null
&& parentExecludeList.contains(item)) {
propUtil.addGreenRefDelta(element, item, eRef,
false);
}
}
}
}
}
}
/**
* Remove assigned steps for the task descriptor
* @param rmItems
* List of steps
*/
private void removeSteps(List rmItems) {
// update the model
if (!rmItems.isEmpty()) {
for (Iterator it = rmItems.iterator(); it.hasNext();) {
org.eclipse.epf.uma.Section item = (org.eclipse.epf.uma.Section) it.next();
actionMgr.doAction(IActionManager.REMOVE, element,
UmaPackage.eINSTANCE.getTaskDescriptor_SelectedSteps(),
item, -1);
if (isSyncFree()) {
actionMgr.doAction(IActionManager.ADD, element,
UmaPackage.eINSTANCE.getTaskDescriptor_SelectedStepsExclude(),
item, -1);
DescriptorPropUtil propUtil = DescriptorPropUtil
.getDesciptorPropUtil(actionMgr);
TaskDescriptor greenParent = (TaskDescriptor) propUtil
.getGreenParentDescriptor(element);
if (greenParent != null) {
EReference eRef = UmaPackage.eINSTANCE
.getTaskDescriptor_SelectedStepsExclude();
List<org.eclipse.epf.uma.Section> parentExecludeList = greenParent
.getSelectedStepsExclude();
propUtil.removeGreenRefDelta(element, item, eRef, false);
if (parentExecludeList == null
|| ! parentExecludeList.contains(item)) {
propUtil.addGreenRefDelta(element, item, eRef,
true);
}
}
}
}
}
}
/**
* Get steps that could be assigned to this task descriptor
* @return
*/
private List getSteps(){
// get all steps
IConfigurationApplicator configApplicator = Providers
.getConfigurationApplicator();
MethodConfiguration config = TngUtil.getOwningProcess(
element).getDefaultContext();
List steps = (List) configApplicator.getReference(
element.getTask(), UmaPackage.eINSTANCE
.getTask_Steps(), config);
// remove already existing steps
steps.removeAll(element.getSelectedSteps());
return steps;
}
protected boolean isSyncFree() {
return ProcessUtil.isSynFree();
}
private void initContentProvider() {
IStructuredContentProvider contentProvider = new AdapterFactoryContentProvider(
TngAdapterFactory.INSTANCE.getNavigatorView_ComposedAdapterFactory()) {
public Object[] getElements(Object object) {
List elements = new ArrayList();
elements.addAll(element.getSelectedSteps());
if (isSyncFree() && !DescriptorPropUtil.getDesciptorPropUtil().isNoAutoSyn(element)) {
if (element.getTask() != null) {
Set validValueSet = new HashSet();
validValueSet.addAll(element.getTask().getSteps());
removeOutdatedReferences(element, UmaPackage.eINSTANCE.getTaskDescriptor_SelectedStepsExclude(), validValueSet);
}
//This is a work around on UI for data layer under sync free
elements = syncFreeReOrder(elements);
elements.addAll(element.getSelectedStepsExclude());
}
return elements.toArray();
}
};
viewer.setContentProvider(contentProvider);
}
private List syncFreeReOrder(List steps) {
List result = new ArrayList();
if (element.getTask() != null) {
List originalSteps = element.getTask().getSteps();
for (Object obj : originalSteps) {
if (steps.contains(obj)) {
result.add(obj);
}
}
} else {
result = steps;
}
return result;
}
private void initLabelProvider() {
ILabelProvider labelProvider = null;
if (isSyncFree()) {
labelProvider = new StepsSyncFreeLabelProvider(
TngAdapterFactory.INSTANCE.getNavigatorView_ComposedAdapterFactory(),
element,
UmaPackage.eINSTANCE.getTaskDescriptor_SelectedSteps(),
getConfiguration()
);
} else {
labelProvider = new AdapterFactoryLabelProvider(
TngAdapterFactory.INSTANCE.getNavigatorView_ComposedAdapterFactory());
}
viewer.setLabelProvider(labelProvider);
}
private void syncFreeUpdateControls() {
ctrl_up.setEnabled(false);
ctrl_down.setEnabled(false);
IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
if ((selection.size() > 0) && (editable)) {
if (isAllDynamic(selection)) {
ctrl_add.setEnabled(false);
ctrl_remove.setEnabled(true);
} else if (isAllExcluded(selection)) {
ctrl_add.setEnabled(true);
ctrl_remove.setEnabled(false);
} else {
ctrl_add.setEnabled(false);
ctrl_remove.setEnabled(false);
}
} else {
ctrl_add.setEnabled(false);
ctrl_remove.setEnabled(false);
}
}
private boolean isAllDynamic(IStructuredSelection selection) {
List<org.eclipse.epf.uma.Section> allDynamic = element.getSelectedSteps();
for (Object obj : selection.toArray()) {
if (obj instanceof org.eclipse.epf.uma.Section) {
if (!allDynamic.contains((org.eclipse.epf.uma.Section)obj)) {
return false;
}
}
}
return true;
}
private boolean isAllExcluded(IStructuredSelection selection) {
List<org.eclipse.epf.uma.Section> allExcluded = element.getSelectedStepsExclude();
for (Object obj : selection.toArray()) {
if (obj instanceof org.eclipse.epf.uma.Section) {
if (!allExcluded.contains((org.eclipse.epf.uma.Section)obj)) {
return false;
}
}
}
return true;
}
public class StepsSyncFreeLabelProvider extends AdapterFactoryLabelProvider implements ITableFontProvider {
private DescriptorPropUtil propUtil = DescriptorPropUtil.getDesciptorPropUtil();
private Font systemFont = Display.getCurrent().getSystemFont();;
private Descriptor desc;
private EReference ref;
private MethodConfiguration config;
public StepsSyncFreeLabelProvider(AdapterFactory adapterFactory, Descriptor desc, EReference ref, MethodConfiguration config) {
super(adapterFactory);
this.desc = desc;
this.ref = ref;
this.config = config;
}
public Font getFont(Object obj, int columnIndex) {
return systemFont;
}
public String getColumnText(Object obj, int columnIndex) {
String original = super.getColumnText(obj, columnIndex);
if (propUtil.isDynamicAndExclude(obj, desc, ref, config)) {
return "--<" + original + ">"; //$NON-NLS-1$ //$NON-NLS-2$
}
return original;
}
}
}