package de.ovgu.cide.tools.featureview;
import java.util.Collections;
import org.eclipse.core.resources.IProject;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.ColorDialog;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.ViewPart;
import de.ovgu.cide.ASTColorChangedEvent;
import de.ovgu.cide.CIDECorePlugin;
import de.ovgu.cide.ColorListChangedEvent;
import de.ovgu.cide.ColoredIDEImages;
import de.ovgu.cide.FileColorChangedEvent;
import de.ovgu.cide.IColorChangeListener;
import de.ovgu.cide.features.FeatureModelManager;
import de.ovgu.cide.features.FeatureModelNotFoundException;
import de.ovgu.cide.features.IFeature;
import de.ovgu.cide.features.IFeatureModel;
import de.ovgu.cide.utils.ColorHelper;
import de.ovgu.cide.utils.EditorUtility;
public class FeatureView extends ViewPart {
private class ActiveProjectListner implements IPartListener {
public void partActivated(IWorkbenchPart part) {
update();
}
private void update() {
IProject ap = getActiveProject();
setProject(ap);
}
public void partBroughtToTop(IWorkbenchPart part) {
update();
}
public void partClosed(IWorkbenchPart part) {
update();
}
public void partDeactivated(IWorkbenchPart part) {
update();
}
public void partOpened(IWorkbenchPart part) {
update();
}
}
private class ColorChangeListner implements IColorChangeListener {
public void astColorChanged(ASTColorChangedEvent event) {
// ignore
}
public void colorListChanged(ColorListChangedEvent event) {
if (event.getProject() == project)
Display.getDefault().asyncExec(new Runnable() {
public void run() {
redraw();
updateValidPanel();
}
});
}
public void fileColorChanged(FileColorChangedEvent event) {
// ignore
}
}
private ActiveProjectListner activeProjectListner;
private ColorChangeListner colorChangeListner;
public FeatureView() {
}
@Override
public void init(IViewSite site) throws PartInitException {
super.init(site);
activeProjectListner = new ActiveProjectListner();
site.getPage().addPartListener(activeProjectListner);
colorChangeListner = new ColorChangeListner();
CIDECorePlugin.getDefault().addColorChangeListener(colorChangeListner);
}
public static final String VIEW_ID = "de.ovgu.cide.core.view.features";
private Action filterAction;
private Action renameAction;
private Action selectColorAction;
private Action findFeatureCodeAction;
// private FeatureTableContentAndLabelProvider provider;
private Table table;
private Label validPanel;
/**
* This is a callback that will allow us to create the viewer and initialize
* it.
*/
public void createPartControl(Composite parent) {
createTable(parent);
createValidPanel(parent);
createLayout(parent);
makeActions();
hookContextMenu();
hookDoubleClickAction();
contributeToActionBars();
}
private void createLayout(Composite parent) {
FormData formData = new FormData(-1, 16);
formData.height = 16;
formData.right = new FormAttachment(100, 0);
formData.left = new FormAttachment(0, 0);
formData.bottom = new FormAttachment(100, 0);
FormData tableLayoutData = new FormData(-1, -1);
tableLayoutData.top = new FormAttachment(0, 0);
tableLayoutData.right = new FormAttachment(100, 0);
tableLayoutData.left = new FormAttachment(0, 0);
tableLayoutData.bottom = new FormAttachment(validPanel);
table.setLayoutData(tableLayoutData);
validPanel.setLayoutData(formData);
parent.setLayout(new FormLayout());
parent.pack();
}
private void createValidPanel(Composite parent) {
validPanel = new Label(parent, SWT.NONE);
validPanel.setText("");
}
private void createTable(Composite parent) {
table = new Table(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL
| SWT.CHECK);
table.setHeaderVisible(false);
TableColumn column;
column = new TableColumn(table, SWT.LEFT);
column.setText("Name");
column.setWidth(120);
column = new TableColumn(table, SWT.LEFT);
column.setText("Color");
column.setWidth(60);
table.addControlListener(new ControlListener() {
public void controlMoved(ControlEvent e) {
}
public void controlResized(ControlEvent e) {
int width = table.getClientArea().width;
if (width > 120) {
table.getColumn(0).setWidth(width - 60);
table.getColumn(1).setWidth(60);
} else {
table.getColumn(0).setWidth(width / 2);
table.getColumn(1).setWidth(width / 2);
}
}
});
setProject(getActiveProject());
table.addSelectionListener(new SelectionListener() {
public void widgetDefaultSelected(SelectionEvent e) {
}
public void widgetSelected(SelectionEvent e) {
if (project != null && e.detail == SWT.CHECK) {
TableItem item = (TableItem) e.item;
IFeature feature = (IFeature) item.getData();
if (item.getGrayed())
item.setChecked(feature.isVisible());
else
try {
feature.setVisible(item.getChecked());
updateValidPanel();
} catch (UnsupportedOperationException ex) {
item.setChecked(feature.isVisible());
}
}
}
});
}
protected void updateValidPanel() {
if (featureModel.isValidSelection(featureModel.getVisibleFeatures())) {
validPanel.setText("Valid configuration");
} else
validPanel.setText("");
}
private IProject project;
private IFeatureModel featureModel;
private Menu featureContextMenu;
private MenuManager featureContextMenuMgr;
private void setProject(IProject newProject) {
if (project == newProject)
return;
project = newProject;
if (project != null)
try {
featureModel = FeatureModelManager.getInstance()
.getFeatureModel(project);
} catch (FeatureModelNotFoundException e) {
project = null;
featureModel = null;
}
else
featureModel = null;
redraw();
}
private void redraw() {
try {
table.setRedraw(false);
IFeature oldSelection = getSelectedFeature();
for (TableItem item : table.getItems()) {
if (item.getBackground(1) != null)
item.getBackground(1).dispose();
}
table.removeAll();
if (project != null && featureModel != null) {
boolean isFiltered = (filterAction != null)
&& filterAction.isChecked();
for (IFeature feature : ColorHelper.sortFeatures(featureModel
.getFeatures()))
if (!isFiltered || feature.isVisible()) {
TableItem item = new TableItem(table, SWT.DEFAULT);
item.setText(0, feature.getName());
item.setText(1, ColorHelper.rgb2str(feature.getRGB()));
item.setBackground(1, new Color(Display.getCurrent(),
ColorHelper.getCombinedRGB(Collections
.singleton(feature))));
item.setChecked(feature.isVisible());
item.setGrayed(!feature.canSetVisible());
item.setData(feature);
}
setSelectedFeature(oldSelection);
}
} finally {
table.setRedraw(true);
}
}
private void setSelectedFeature(IFeature feature) {
if (feature != null)
for (TableItem item : table.getItems()) {
if (item.getData() == feature) {
table.setSelection(item);
break;
}
}
table.setSelection(-1);
}
private void hookContextMenu() {
featureContextMenuMgr = new MenuManager("#PopupMenu");
featureContextMenuMgr.setRemoveAllWhenShown(true);
featureContextMenuMgr.addMenuListener(new IMenuListener() {
public void menuAboutToShow(IMenuManager manager) {
FeatureView.this.fillContextMenu(manager);
}
});
Menu menu = featureContextMenuMgr.createContextMenu(table);
table.setMenu(menu);
// getSite().registerContextMenu(menuMgr, table.get);
}
private void contributeToActionBars() {
IActionBars bars = getViewSite().getActionBars();
fillLocalToolBar(bars.getToolBarManager());
}
private void fillContextMenu(IMenuManager manager) {
boolean enabled = getSelectedFeature() != null;
renameAction.setEnabled(enabled && getSelectedFeature().canSetName());
selectColorAction.setEnabled(enabled
&& getSelectedFeature().canSetRGB());
findFeatureCodeAction.setEnabled(enabled);
manager.add(renameAction);
manager.add(selectColorAction);
manager.add(findFeatureCodeAction);
// Other plug-ins can contribute there actions here
manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
}
private void fillLocalToolBar(IToolBarManager manager) {
manager.add(filterAction);
}
private void makeActions() {
filterAction = new Action("Filter", IAction.AS_CHECK_BOX) {
public void run() {
redraw();
}
};
filterAction.setText("Filter");
filterAction.setToolTipText("Hide invisible features");
ColoredIDEImages.setImageDescriptors(filterAction,
ColoredIDEImages.INTERACTION);
renameAction = new Action("Rename...") {
public void run() {
IFeature feature = getSelectedFeature();
if (feature == null)
return;
String oldName = feature.getName();
InputDialog input = new InputDialog(getSite().getShell(),
"Rename IFeature", "New name:", oldName,
new IInputValidator() {
public String isValid(String newText) {
if (newText.length() == 0)
return "Name must not be empty";
return null;
}
});
if (input.open() == InputDialog.OK)
try {
feature.setName(input.getValue());
} catch (UnsupportedOperationException e) {
// nothing yet. TODO prevent renaming features that
// cannot
// be renamed
}
}
};
renameAction.setToolTipText("Rename IFeature");
renameAction.setAccelerator(SWT.F2);
selectColorAction = new Action("Select color...") {
@Override
public void run() {
IFeature feature = getSelectedFeature();
if (feature == null)
return;
RGB oldColor = feature.getRGB();
ColorDialog colorDialog = new ColorDialog(getSite().getShell());
colorDialog.setRGB(oldColor);
colorDialog.setText("Color for IFeature \"" + feature.getName()
+ "\"");
RGB newColor = colorDialog.open();
if (newColor != null && newColor != oldColor)
try {
feature.setRGB(newColor);
} catch (UnsupportedOperationException e) {
// nothing yet. TODO prevent renaming features that
// cannot be renamed
}
}
};
findFeatureCodeAction = new Action("Find feature's code") {
@Override
public void run() {
MessageDialog.openWarning(getSite().getShell(), "Error",
"not implemented yet");
super.run();
}
};
}
protected IFeature getSelectedFeature() {
int idx = table.getSelectionIndex();
if (idx == -1)
return null;
return (IFeature) table.getItem(idx).getData();
}
private void hookDoubleClickAction() {
// tree.addSelectionListener(new SelectionListener() {
// public void widgetDefaultSelected(SelectionEvent e) {
// }
//
// public void widgetSelected(SelectionEvent e) {
// jumpToAction.run();
// }
// });
}
// private void showMessage(String message) {
// MessageDialog.openInformation(tree.getShell(), "Feature Interactions",
// message);
// }
/**
* Passing the focus request to the viewer's control.
*/
public void setFocus() {
table.setFocus();
}
private IProject getActiveProject() {
IEditorPart part = EditorUtility.getActiveEditor();
if (part != null) {
IEditorInput input = part.getEditorInput();
if (input instanceof IFileEditorInput)
return ((IFileEditorInput) input).getFile().getProject();
}
return null;
}
@Override
public void dispose() {
setProject(null);
if (activeProjectListner != null)
getSite().getPage().removePartListener(activeProjectListner);
if (colorChangeListner != null)
CIDECorePlugin.getDefault().removeColorChangeListener(
colorChangeListner);
}
}