/* FeatureIDE - An IDE to support feature-oriented software development * Copyright (C) 2005-2009 FeatureIDE Team, University of Magdeburg * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * * See http://www.fosd.de/featureide/ for further information. */ package featureide.fm.ui.views; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.io.FileNotFoundException; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.draw2d.ConnectionLayer; import org.eclipse.gef.LayerConstants; import org.eclipse.gef.editparts.ScalableFreeformRootEditPart; import org.eclipse.gef.ui.parts.GraphicalViewerImpl; import org.eclipse.gef.ui.parts.ScrollingGraphicalViewer; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IPartListener; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.part.ViewPart; import org.eclipse.ui.progress.UIJob; import featureide.fm.core.FeatureModel; import featureide.fm.core.editing.evaluation.Evaluation; import featureide.fm.core.io.UnsupportedModelException; import featureide.fm.core.io.guidsl.FeatureModelReader; import featureide.fm.ui.FMUIPlugin; import featureide.fm.ui.editors.FeatureModelEditor; import featureide.fm.ui.editors.featuremodel.GEFImageWriter; import featureide.fm.ui.editors.featuremodel.GUIDefaults; import featureide.fm.ui.editors.featuremodel.editparts.GraphicalEditPartFactory; import featureide.fm.ui.editors.featuremodel.layouts.FeatureDiagramLayoutManager; import featureide.fm.ui.editors.featuremodel.layouts.LevelOrderLayout; import featureide.fm.ui.views.featuremodeleditview.ViewContentProvider; import featureide.fm.ui.views.featuremodeleditview.ViewLabelProvider; /** * A view to calculate the category an edit. Given an open feature model editor * the current editing version is compared to the last saved model. * * @author Thomas Thuem */ public class FeatureModelEditView extends ViewPart { public static final String ID = FMUIPlugin.PLUGIN_ID + ".views.FeatureModelEditView"; private TreeViewer viewer; private FeatureModelEditor featureModelEditor; private Job job; private IPartListener editorListener = new IPartListener() { public void partOpened(IWorkbenchPart part) { } public void partDeactivated(IWorkbenchPart part) { } public void partClosed(IWorkbenchPart part) { if (part == featureModelEditor) setGrammarEditor(null); } public void partBroughtToTop(IWorkbenchPart part) { if (part instanceof IEditorPart) setGrammarEditor(part); } public void partActivated(IWorkbenchPart part) { } }; private PropertyChangeListener modelListener = new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { refresh(); } }; private ViewContentProvider contentProvider = new ViewContentProvider(this); public void createPartControl(Composite parent) { viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); viewer.setContentProvider(contentProvider); viewer.setLabelProvider(new ViewLabelProvider()); viewer.setInput(getViewSite()); getSite().getPage().addPartListener(editorListener); IWorkbenchPage page = getSite().getPage(); setGrammarEditor(page.getActiveEditor()); } @Override public void dispose() { if (job != null) { if (job.getState() == Job.RUNNING) job.cancel(); job = null; } getSite().getPage().removePartListener(editorListener); if (featureModelEditor != null) { featureModelEditor.getOriginalFeatureModel().removeListener( modelListener); featureModelEditor.getFeatureModel().removeListener(modelListener); featureModelEditor = null; } super.dispose(); } /** * Passing the focus request to the viewer's control. */ public void setFocus() { viewer.getControl().setFocus(); } private Job evaluation; private void setGrammarEditor(IWorkbenchPart activeEditor) { if (featureModelEditor == activeEditor) return; if (featureModelEditor != null) { featureModelEditor.getOriginalFeatureModel().removeListener( modelListener); featureModelEditor.getFeatureModel().removeListener(modelListener); featureModelEditor = null; } if (activeEditor instanceof FeatureModelEditor) { featureModelEditor = (FeatureModelEditor) activeEditor; featureModelEditor.getOriginalFeatureModel().addListener(modelListener); featureModelEditor.getFeatureModel().addListener(modelListener); if (evaluation == null && featureModelEditor != null && featureModelEditor.getGrammarFile().getResource().getProject().getName().startsWith("EvaluationTest")) { evaluation = new Job("Evaluation Test") { @Override protected IStatus run(IProgressMonitor monitor) { Evaluation.evaluate(featureModelEditor.getGrammarFile().getResource().getProject()); return Status.OK_STATUS; } }; evaluation.setPriority(Job.LONG); evaluation.schedule(); UIJob conversion = new UIJob("Converting Feature Models") { @Override public IStatus runInUIThread(IProgressMonitor monitor) { try { convertModelToBitmapTest(featureModelEditor.getGrammarFile().getResource().getProject().getFolder("models")); } catch (Exception e) { e.printStackTrace(); } return Status.OK_STATUS; } public void convertModelToBitmapTest(IFolder folder) throws CoreException { for (IResource res : folder.members()) if (res instanceof IFile && res.getName().endsWith(".m")) { IFile fmFile = (IFile) res; try { FeatureModel fm = new FeatureModel(); FeatureModelReader reader = new FeatureModelReader(fm); reader.readFromFile(fmFile); String imageName = fmFile.getRawLocation().toOSString(); imageName = imageName.substring(0, imageName.length()-".m".length()) + ".png"; createBitmap(fm, new File(imageName)); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (UnsupportedModelException e) { e.printStackTrace(); } } folder.refreshLocal(IResource.DEPTH_ONE, null); } private void createBitmap(FeatureModel featureModel, File file) { GraphicalViewerImpl graphicalViewer = new ScrollingGraphicalViewer(); graphicalViewer.createControl(viewer.getControl().getParent()); graphicalViewer.getControl().setBackground(GUIDefaults.DIAGRAM_BACKGROUND); graphicalViewer.setEditPartFactory(new GraphicalEditPartFactory()); ScalableFreeformRootEditPart rootEditPart = new ScalableFreeformRootEditPart(); ((ConnectionLayer) rootEditPart .getLayer(LayerConstants.CONNECTION_LAYER)) .setAntialias(SWT.ON); graphicalViewer.setRootEditPart(rootEditPart); graphicalViewer.setContents(featureModel); FeatureDiagramLayoutManager layoutManager = new LevelOrderLayout(); layoutManager.layout(featureModel); GEFImageWriter.writeToFile(graphicalViewer, file); } }; conversion.setPriority(Job.LONG); conversion.schedule(); } } refresh(); } private void refresh() { if (job != null && job.getState() == Job.RUNNING) job.cancel(); job = new Job("Updating Feature Model Edits") { @Override protected IStatus run(IProgressMonitor monitor) { if (featureModelEditor == null) contentProvider.defaultContent(); else contentProvider.calculateContent(featureModelEditor.getOriginalFeatureModel(), featureModelEditor.getFeatureModel()); return Status.OK_STATUS; } }; job.setPriority(Job.LONG); job.schedule(); } public TreeViewer getViewer() { return viewer; } }