/******************************************************************************* * Copyright (c) 2015 ARM Ltd. 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: * Eclipse Project - generation from template * ARM Ltd and ARM Germany GmbH - application-specific implementation *******************************************************************************/ package com.arm.cmsis.pack.ui.editors; import java.io.ByteArrayInputStream; import java.io.File; import java.nio.charset.Charset; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceChangeEvent; import org.eclipse.core.resources.IResourceChangeListener; import org.eclipse.core.resources.IResourceDelta; import org.eclipse.core.resources.IResourceDeltaVisitor; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IEditorSite; import org.eclipse.ui.IFileEditorInput; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.PartInitException; import org.eclipse.ui.ide.IGotoMarker; import org.eclipse.ui.ide.ResourceUtil; import org.eclipse.ui.part.FileEditorInput; import org.eclipse.ui.part.MultiPageEditorPart; import org.eclipse.ui.views.contentoutline.IContentOutlinePage; import com.arm.cmsis.pack.CpPlugIn; import com.arm.cmsis.pack.common.CmsisConstants; import com.arm.cmsis.pack.data.CpPack; import com.arm.cmsis.pack.data.ICpItem; import com.arm.cmsis.pack.enums.EEvaluationResult; import com.arm.cmsis.pack.events.IRteEventListener; import com.arm.cmsis.pack.events.RteEvent; import com.arm.cmsis.pack.info.ICpComponentInfo; import com.arm.cmsis.pack.info.ICpConfigurationInfo; import com.arm.cmsis.pack.info.ICpPackInfo; import com.arm.cmsis.pack.parser.CpConfigParser; import com.arm.cmsis.pack.rte.IRteModelController; import com.arm.cmsis.pack.rte.RteModel; import com.arm.cmsis.pack.rte.components.IRteComponentItem; import com.arm.cmsis.pack.rte.dependencies.IRteDependencyItem; import com.arm.cmsis.pack.rte.packs.IRtePackFamily; import com.arm.cmsis.pack.ui.CpPlugInUI; import com.arm.cmsis.pack.ui.CpStringsUI; /** * An example showing how to create an RTE configuration multi-page editor. This * example has 4 pages: * <ul> * <li>page 0 contains an RteManagerWidget * <li>page 1 contains an RteDesviceInfo * <li>page 1 contains an RtePackSelectorWidget * </ul> */ public class RteEditor extends MultiPageEditorPart implements IResourceChangeListener, IRteEventListener, IGotoMarker { private RteComponentPage rteComponentPage; private RteDevicePage rteDevicePage; private RtePackPage rtePackPage; private int componentPageIndex = 0; private int devicePageIndex = 1; private int packPageIndex = 2; private int activePageIndex = 0; // initially the page with index 0 is activated IRteModelController fModelController = null; CpConfigParser parser = null; IFile iFile; public RteEditor() { super(); parser = new CpConfigParser(); CpPlugIn.addRteListener(this); ResourcesPlugin.getWorkspace().addResourceChangeListener(this); } void createRteManagerPage() { rteComponentPage = new RteComponentPage(); Composite composite = rteComponentPage.createControl(getContainer()); componentPageIndex = addPage(composite); setPageText(componentPageIndex, CpStringsUI.RteConfigurationEditor_ComponentsTab); } void createPackSelectorPage() { rtePackPage = new RtePackPage(); Composite composite = rtePackPage.createControl(getContainer()); packPageIndex = addPage(composite); setPageText(packPageIndex, CpStringsUI.RteConfigurationEditor_PacksTab); } void createDeviceSelectorPage() { rteDevicePage = new RteDevicePage(); Composite composite = rteDevicePage.createControl(getContainer()); devicePageIndex = addPage(composite); setPageText(devicePageIndex, CpStringsUI.RteDevicePage_Device); } @Override protected void setInput(IEditorInput input) { super.setInput(input); iFile = ResourceUtil.getFile(input); String title= input.getName(); setPartName(title); } @Override protected void createPages() { createRteManagerPage(); createDeviceSelectorPage(); createPackSelectorPage(); createConfiguration(); } protected void createConfiguration() { File file = iFile.getLocation().toFile(); ICpItem root = parser.parseFile(file.getAbsolutePath()); fModelController = new RteEditorController(new RteModel()); if (root != null) { ICpConfigurationInfo info = (ICpConfigurationInfo) root; fModelController.setConfigurationInfo(info); rteComponentPage.setModelController(fModelController); rteDevicePage.setModelController(fModelController); rtePackPage.setModelController(fModelController); fModelController.addListener(this); } } @Override public void dispose() { ResourcesPlugin.getWorkspace().removeResourceChangeListener(this); CpPlugIn.removeRteListener(this); parser = null; fModelController = null; rteComponentPage = null; rtePackPage = null; rteDevicePage = null; super.dispose(); } protected String getXmlString() { if (fModelController != null) { ICpConfigurationInfo info = fModelController.getConfigurationInfo(); return parser.writeToXmlString(info); } return CmsisConstants.EMPTY_STRING; } @Override public void doSave(IProgressMonitor monitor) { fModelController.commit(); String xml = getXmlString(); try { iFile.setContents(new ByteArrayInputStream(xml.getBytes(Charset.defaultCharset())), true, true, monitor); iFile.refreshLocal(IResource.DEPTH_ZERO, monitor); } catch (CoreException e) { } firePropertyChange(IEditorPart.PROP_DIRTY); } @Override public void doSaveAs() { fModelController.commit(); String xml = getXmlString(); try { IProgressMonitor monitor = new NullProgressMonitor(); iFile.setContents(new ByteArrayInputStream(xml.getBytes(Charset.defaultCharset())), true, true, monitor); iFile.refreshLocal(IResource.DEPTH_ZERO, monitor); } catch (CoreException e) { } firePropertyChange(IEditorPart.PROP_DIRTY); } @Override public void gotoMarker(IMarker marker) { try { IRteDependencyItem depItem = (IRteDependencyItem) marker.getAttribute(CpPlugInUI.RTE_PROBLEM_MARKER_DEP_ITEM); if (depItem == null) { return; } IRteComponentItem rteComponent = depItem.getComponentItem(); if (rteComponent == null) { return; } ICpComponentInfo ci = rteComponent.getActiveCpComponentInfo(); boolean packInstalled = ci == null ? false : ci.getPackInfo().getPack() != null; if (ci != null && depItem.getEvaluationResult() != EEvaluationResult.UNAVAILABLE && !packInstalled) { setActivePage(2); ICpPackInfo pi = ci.getPackInfo(); String packId = pi.isVersionFixed() ? pi.getId() : pi.getPackFamilyId(); IRtePackFamily packFamily = fModelController.getRtePackCollection().getRtePackFamily(CpPack.familyFromId(packId)); fModelController.emitRteEvent(RteEvent.PACK_FAMILY_SHOW, packFamily); } else { setActivePage(0); fModelController.emitRteEvent(RteEvent.COMPONENT_SHOW, fModelController.getComponents().findChild(rteComponent.getKeyPath(), false)); } } catch (CoreException e) { } } /** * The <code>MultiPageEditorExample</code> implementation of this method * checks that the input is an instance of <code>IFileEditorInput</code>. */ @Override public void init(IEditorSite site, IEditorInput editorInput) throws PartInitException { if (!(editorInput instanceof IFileEditorInput)) { throw new PartInitException(CpStringsUI.RteConfigurationEditor_InvalidInput); } super.init(site, editorInput); } @Override public boolean isSaveAsAllowed() { return false; } @Override protected void pageChange(int newPageIndex) { super.pageChange(newPageIndex); if (activePageIndex == newPageIndex) { return; } activePageIndex = newPageIndex; if (fModelController != null) { fModelController.updateConfigurationInfo(); } } @Override public void handle(RteEvent event) { if (fModelController == null) { return; } switch (event.getTopic()) { case RteEvent.CONFIGURATION_MODIFIED: case RteEvent.COMPONENT_SELECTION_MODIFIED: case RteEvent.FILTER_MODIFIED: firePropertyChange(IEditorPart.PROP_DIRTY); return; case RteEvent.PACKS_RELOADED: case RteEvent.PACKS_UPDATED: if (fModelController != null) { fModelController.reloadPacks(); } break; case RteEvent.GPDSC_CHANGED: if (fModelController != null) { if(fModelController.isGeneratedPackUsed((String)event.getData())){ fModelController.update(); } } break; default: } } @Override public boolean isDirty() { if (fModelController != null) { return fModelController.isModified(); } return false; } public IRteModelController getModelController() { return fModelController; } /** * Closes all project files on project close. */ @Override public void resourceChanged(final IResourceChangeEvent event) { if (event.getType() == IResourceChangeEvent.PRE_CLOSE) { Display.getDefault().asyncExec(() -> { IProject project = iFile.getProject(); IWorkbenchPage[] pages = getSite().getWorkbenchWindow().getPages(); for (int i = 0; i < pages.length; i++) { if (project.equals(event.getResource())) { IEditorPart editorPart = ResourceUtil.findEditor(pages[i], iFile); pages[i].closeEditor(editorPart, true); } } }); } if (event.getType() == IResourceChangeEvent.POST_CHANGE) { IResourceDelta resourseDelta = event.getDelta(); IResourceDeltaVisitor deltaVisitor = new IResourceDeltaVisitor() { @Override public boolean visit(IResourceDelta delta) { IResource resource = delta.getResource(); int type = resource.getType(); if (type == IResource.ROOT || type == IResource.PROJECT) { return true; // workspace or project => visit children } int kind = delta.getKind(); int flags = delta.getFlags(); if (type == IResource.FILE && kind == IResourceDelta.REMOVED && resource.equals(iFile)) { if ((flags & IResourceDelta.MOVED_TO) == IResourceDelta.MOVED_TO) { // renamed IPath newPath = delta.getMovedToPath(); IFile r = (IFile) ResourcesPlugin.getWorkspace().getRoot().findMember(newPath); final FileEditorInput fileEditorInput = new FileEditorInput(r); Display.getDefault().asyncExec(() -> setInput(fileEditorInput)); return false; } else if (flags == 0) { // project deleted Display.getDefault().asyncExec(() -> { RteEditor.this.getEditorSite().getPage() .closeEditor(RteEditor.this, true); }); return false; } return false; } return true; } }; try { resourseDelta.accept(deltaVisitor); } catch (CoreException e) { e.printStackTrace(); } } } // bind to framework @Override @SuppressWarnings({ "rawtypes", "unchecked" }) public Object getAdapter(Class required) { if (IContentOutlinePage.class.equals(required)) { // two outline views for Components and xml views. // These views must implements IContentOutlinePage or extends // ContentOutlinePage // OutlineView ov = new OutlineView(); // return ov; if (getActivePage() == 1) { // return new XMLContentOutlinePage(this); } } return super.getAdapter(required); } }