/******************************************************************************* * Copyright (C) 2003-2006, 2013, Guillaume Brocker * Copyright (C) 2015-2016, Andre Bossert * * 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: * Guillaume Brocker - Initial API and implementation * Andre Bossert - Add ability to use Doxyfile not in project scope * ******************************************************************************/ package eclox.ui.editor; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.net.URI; import java.util.Iterator; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IFileEditorInput; import org.eclipse.ui.IMemento; import org.eclipse.ui.IPersistableEditor; import org.eclipse.ui.forms.editor.FormEditor; import org.eclipse.ui.ide.FileStoreEditorInput; import eclox.core.doxyfiles.Doxyfile; import eclox.core.doxyfiles.ISettingValueListener; import eclox.core.doxyfiles.Setting; import eclox.core.doxyfiles.io.Serializer; import eclox.ui.editor.internal.ResourceChangeListener; /** * Implements the doxyfile editor. * * @author gbrocker */ /** * @author willy * */ public class Editor extends FormEditor implements ISettingValueListener, IPersistableEditor { public final static String PROP_SETTING_DIRTY = "dirty"; ///< the name of the property attached to a dirty setting. public final static String SAVED_ACTIVE_PAGE_ID = "SavedActivePageId"; ///< Identifies the memo entry containing the identifier if the saved active page identifier. private Doxyfile doxyfile; ///< The doxyfile content. private ResourceChangeListener resourceChangeListener; ///< the resource listener that will manage the editor life-cycle private boolean dirty = false; ///< The dirty state of the editor private IMemento savedState; ///< References a saved state to restore, null otherwise. /** * @see org.eclipse.ui.forms.editor.FormEditor#addPages() */ protected void addPages() { try { addPage(new eclox.ui.editor.basic.Page(this)); addPage(new eclox.ui.editor.advanced.Page(this)); // TODO reactivate //this.addPage(new SourcePage(this)); // Restores the saved active page. String savedPageId = (savedState != null) ? savedState.getString(SAVED_ACTIVE_PAGE_ID) : null; setActivePage(savedPageId); } catch( Throwable throwable ) {} } /** * @see org.eclipse.ui.ISaveablePart#doSave(org.eclipse.core.runtime.IProgressMonitor) */ public void doSave( IProgressMonitor monitor ) { // Retrieves the file input. IEditorInput editorInput = this.getEditorInput(); IFile ifile = null; File file = null; if (editorInput instanceof IFileEditorInput) { ifile = ((IFileEditorInput)editorInput).getFile(); } else { URI fileuri = ((FileStoreEditorInput)editorInput).getURI(); file = new File(fileuri.getPath()); } try { // Commits all pending changes. commitPages(true); // Stores the doxyfile content. Serializer serializer = new Serializer(doxyfile); if (ifile != null) { ifile.setContents(serializer, false, true, monitor); } else { FileOutputStream outputStream = null; try { // write the inputStream to a FileOutputStream outputStream = new FileOutputStream(file); int read = 0; byte[] bytes = new byte[1024]; while ((read = serializer.read(bytes)) != -1) { outputStream.write(bytes, 0, read); } } catch (IOException e) { e.printStackTrace(); } finally { if (outputStream != null) { try { outputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } // Clears the dirty property set on some settings. Iterator<?> i = doxyfile.settingIterator(); while( i.hasNext() ) { Setting setting = (Setting) i.next(); setting.removeProperty( PROP_SETTING_DIRTY ); } // Resets the dirty flag. this.dirty = false; this.firePropertyChange( IEditorPart.PROP_DIRTY ); } catch( Throwable throwable ) { MessageDialog.openError(getSite().getShell(), "Unexpected Error", throwable.toString()); } } /** * @see org.eclipse.ui.ISaveablePart#doSaveAs() */ public void doSaveAs() { // TODO implement "save as" } /** * Retrieves the doxyfile attached to the editor. * * @return a doxyfile instance */ public Doxyfile getDoxyfile() { return this.doxyfile; } /** * @see org.eclipse.ui.ISaveablePart#isSaveAsAllowed() */ public boolean isSaveAsAllowed() { // TODO implement "save as" return false; } /** * @see eclox.doxyfiles.ISettingListener#settingValueChanged(eclox.doxyfiles.Setting) */ public void settingValueChanged( Setting setting ) { // Updates the internal editor state. this.dirty = true; this.firePropertyChange( IEditorPart.PROP_DIRTY ); // Assigns a dynamic property to the setting. setting.setProperty( PROP_SETTING_DIRTY, "yes" ); } /** * @see org.eclipse.ui.IWorkbenchPart#dispose() */ public void dispose() { // Unregisters the editor from the settings Iterator<?> i = this.doxyfile.settingIterator(); while( i.hasNext() == true ) { Setting setting = (Setting) i.next(); setting.removeSettingListener( this ); } // Un-references the doxyfile. this.doxyfile = null; // Detaches the resource change listener ResourcesPlugin.getWorkspace().removeResourceChangeListener( resourceChangeListener ); resourceChangeListener = null; // Continue... super.dispose(); } /** * @see org.eclipse.ui.ISaveablePart#isDirty() */ public boolean isDirty() { return super.isDirty() || this.dirty; } /** * @see org.eclipse.ui.IPersistableEditor#restoreState(org.eclipse.ui.IMemento) */ public void restoreState(IMemento memento) { savedState = memento; } /** * @see org.eclipse.ui.IPersistable#saveState(org.eclipse.ui.IMemento) */ public void saveState(IMemento memento) { memento.putString(SAVED_ACTIVE_PAGE_ID, getActivePageInstance().getId()); } /** * @see org.eclipse.ui.part.EditorPart#setInput(org.eclipse.ui.IEditorInput) */ protected void setInput(IEditorInput input) { super.setInput(input); try { IFile ifile = null; File file = null; if (input instanceof IFileEditorInput) { ifile = ((IFileEditorInput)input).getFile(); } else if (input instanceof IAdaptable) { IAdaptable adaptable = (IAdaptable) input; ifile = (IFile) adaptable.getAdapter(IFile.class); if (ifile == null) { if (adaptable instanceof FileStoreEditorInput) { URI fileuri = ((FileStoreEditorInput) adaptable).getURI(); file = new File(fileuri.getPath()); } else { file = (File) adaptable.getAdapter(File.class); } } } // Attaches the resource change listener resourceChangeListener = new ResourceChangeListener(this); ResourcesPlugin.getWorkspace().addResourceChangeListener( resourceChangeListener ); // Parses the doxyfile and attaches to all settings. this.doxyfile = new Doxyfile(ifile, file); this.doxyfile.load(); Iterator<?> i = this.doxyfile.settingIterator(); while( i.hasNext() == true ) { Setting setting = (Setting) i.next(); setting.addSettingListener( this ); } // Continue initialization. setPartName( input.getName() ); } catch( Throwable throwable ) { MessageDialog.openError(getSite().getShell(), "Unexpected Error", throwable.toString()); } } }