Mercurial > hg > thermostat-tools-eclipse
view com.redhat.thermostat.tools.eclipse.plugin/src/com/redhat/thermostat/tools/eclipse/plugin/editor/MultiPageEditor.java @ 98:c3002fd38e27
Fix dirty state handling for edit pages
author | Omair Majid <omajid@redhat.com> |
---|---|
date | Fri, 07 Feb 2014 12:57:54 -0500 |
parents | 8f2dd0dbdb87 |
children |
line wrap: on
line source
package com.redhat.thermostat.tools.eclipse.plugin.editor; import java.io.ByteArrayOutputStream; import java.nio.charset.StandardCharsets; import java.util.Iterator; import java.util.Objects; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResourceChangeEvent; import org.eclipse.core.resources.IResourceChangeListener; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.text.DocumentEvent; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IDocumentListener; 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.forms.editor.FormEditor; import org.eclipse.ui.forms.editor.IFormPage; import org.eclipse.ui.part.FileEditorInput; import org.eclipse.wst.sse.ui.StructuredTextEditor; import com.redhat.thermostat.tools.eclipse.plugin.model.Plugin; import com.redhat.thermostat.tools.eclipse.plugin.model.PluginModelReaderWriter; public class MultiPageEditor extends FormEditor implements IResourceChangeListener { private static final int INDEX_SOURCE = 3; private StructuredTextEditor editor; /** * Helps synchronizing changes between editor and model. Not related to * {@code isDirty()}. */ private boolean editorIsDirty = false; private PluginModelReaderWriter modelHelper; private Plugin model; private int oldPage = -1; public MultiPageEditor() { super(); ResourcesPlugin.getWorkspace().addResourceChangeListener(this); } @Override public void init(IEditorSite site, IEditorInput editorInput) throws PartInitException { if (!(editorInput instanceof IFileEditorInput)) throw new PartInitException("Invalid Input: Must be IFileEditorInput"); //$NON-NLS-1$ super.init(site, editorInput); try { IFile file = ((IFileEditorInput)getEditorInput()).getFile(); modelHelper = new PluginModelReaderWriter(file); model = modelHelper.loadModel(file.getContents()); Objects.requireNonNull(model); } catch (CoreException e) { e.printStackTrace(); } } @Override protected void addPages() { try { OverviewPage overview = new OverviewPage(this, modelHelper.getPluginName()); addPage(overview); CommandsPage commandsPage = new CommandsPage(this, model); addPage(commandsPage); ExtensionsPage extensionsPage = new ExtensionsPage(this, model); addPage(extensionsPage); createSourcePage(); } catch (PartInitException pie) { throw new RuntimeException(pie); // ErrorDialog.openError(getSite().getShell(), // "Error creating nested text editor", null, e.getStatus()); } } void createSourcePage() throws PartInitException { editor = new StructuredTextEditor(); addPage(editor, getEditorInput()); setPageText(INDEX_SOURCE, editor.getTitle()); getDocument().addDocumentListener(new IDocumentListener() { @Override public void documentChanged(DocumentEvent event) { editorIsDirty = true; } @Override public void documentAboutToBeChanged(DocumentEvent event) { // nothing to do } }); } @Override public void dispose() { ResourcesPlugin.getWorkspace().removeResourceChangeListener(this); super.dispose(); } @Override protected void pageChange(int newPageIndex) { if (oldPage != -1) { if (oldPage == INDEX_SOURCE && editorIsDirty) { updateModelFromSource(); } else if (newPageIndex == INDEX_SOURCE) { updateSourceFromModel(); } } super.pageChange(newPageIndex); oldPage = newPageIndex; } @Override public void doSave(IProgressMonitor monitor) { if (getActivePage() != INDEX_SOURCE) { updateSourceFromModel(); } // save all the pages. this doesn't really do the saving, but tells each // page that it is being saved, so they can get a chance to update the // model and deal with changes Iterator iter = pages.iterator(); while (iter.hasNext()) { Object obj = iter.next(); if (obj instanceof IFormPage) { ((IFormPage) obj).doSave(monitor); } } // actually save the model editor.doSave(monitor); } @Override public boolean isSaveAsAllowed() { return false; } @Override public void doSaveAs() { throw new AssertionError("SaveAs is not allowed"); //$NON-NLS-1$ } private void updateSourceFromModel() { ByteArrayOutputStream baos = new ByteArrayOutputStream(); modelHelper.saveModel(model, baos); String modelSource = new String(baos.toByteArray(), StandardCharsets.UTF_8); if (!getDocument().get().equals(modelSource)) { getDocument().set(modelSource); } editorIsDirty = false; } private void updateModelFromSource() { model = modelHelper.loadModel(getDocument().get()); editorIsDirty = false; } private IDocument getDocument() { return editor.getDocumentProvider().getDocument(editor.getEditorInput()); } /** * Closes all project files on project close. */ public void resourceChanged(final IResourceChangeEvent event) { if (event.getType() == IResourceChangeEvent.PRE_CLOSE) { Display.getDefault().asyncExec(new Runnable() { public void run() { IWorkbenchPage[] pages = getSite().getWorkbenchWindow() .getPages(); for (int i = 0; i < pages.length; i++) { if (((FileEditorInput) editor.getEditorInput()) .getFile().getProject() .equals(event.getResource())) { IEditorPart editorPart = pages[i].findEditor(editor .getEditorInput()); pages[i].closeEditor(editorPart, true); } } } }); } } }