/** * This file Copyright (c) 2005-2008 Aptana, Inc. This program is * dual-licensed under both the Aptana Public License and the GNU General * Public license. You may elect to use one or the other of these licenses. * * This program is distributed in the hope that it will be useful, but * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or * NONINFRINGEMENT. Redistribution, except as permitted by whichever of * the GPL or APL you select, is prohibited. * * 1. For the GPL license (GPL), you can redistribute and/or modify this * program under the terms of the GNU General Public License, * Version 3, as published by the Free Software Foundation. You should * have received a copy of the GNU General Public License, Version 3 along * with this program; if not, write to the Free Software Foundation, Inc., 51 * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Aptana provides a special exception to allow redistribution of this file * with certain other free and open source software ("FOSS") code and certain additional terms * pursuant to Section 7 of the GPL. You may view the exception and these * terms on the web at http://www.aptana.com/legal/gpl/. * * 2. For the Aptana Public License (APL), this program and the * accompanying materials are made available under the terms of the APL * v1.0 which accompanies this distribution, and is available at * http://www.aptana.com/legal/apl/. * * You may view the GPL, Aptana's exception and additional terms, and the * APL in the file titled license.html at the root of the corresponding * plugin containing this source file. * * Any modifications to this file must keep this entire header intact. */ package com.aptana.ide.editor.css; import java.io.File; import java.io.IOException; import java.net.URI; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.jface.text.IDocument; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorSite; import org.eclipse.ui.IPartListener; import org.eclipse.ui.IPartService; import org.eclipse.ui.IPathEditorInput; import org.eclipse.ui.IURIEditorInput; import org.eclipse.ui.IWindowListener; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.internal.editors.text.NonExistingFileEditorInput; import org.eclipse.ui.part.FileEditorInput; import org.eclipse.ui.texteditor.IDocumentProvider; import com.aptana.ide.core.FileUtils; import com.aptana.ide.core.ui.CoreUIUtils; import com.aptana.ide.editor.css.CSSDocumentProvider.CSSFileInfo; import com.aptana.ide.editor.css.context.CSSContextAwareness; import com.aptana.ide.editor.css.preferences.IPreferenceConstants; import com.aptana.ide.editors.unified.DocumentSourceProvider; import com.aptana.ide.editors.unified.IFileServiceFactory; import com.aptana.ide.editors.unified.IUnifiedEditorContributor; import com.aptana.ide.editors.unified.UnifiedEditor; import com.aptana.ide.editors.unified.context.IContextAwareness; /** * @author Robin Debreuil * @author Pavel Petrochenko */ public class CSSEditor extends UnifiedEditor { /** * Internal part and shell activation listener for triggering state validation. */ private class ActivationListener implements IPartListener, IWindowListener { /** Cache of the active workbench part. */ private IWorkbenchPart fActivePart; /** Indicates whether activation handling is currently be done. */ private boolean fIsHandlingActivation= false; /** * The part service. */ private IPartService fPartService; /** * Creates this activation listener. * * @param partService the part service on which to add the part listener */ public ActivationListener(IPartService partService) { fPartService= partService; fPartService.addPartListener(this); PlatformUI.getWorkbench().addWindowListener(this); } /** * Disposes this activation listener. */ public void dispose() { fPartService.removePartListener(this); PlatformUI.getWorkbench().removeWindowListener(this); fPartService= null; } /** * @see IPartListener#partActivated(org.eclipse.ui.IWorkbenchPart) */ public void partActivated(IWorkbenchPart part) { if (part instanceof MultiPageCSSEditor) { fActivePart = ((MultiPageCSSEditor) part).getEditor(); } else { fActivePart= part; } handleActivation(); } /** * @see IPartListener#partBroughtToTop(org.eclipse.ui.IWorkbenchPart) */ public void partBroughtToTop(IWorkbenchPart part) { } /** * @see IPartListener#partClosed(org.eclipse.ui.IWorkbenchPart) */ public void partClosed(IWorkbenchPart part) { } /** * @see IPartListener#partDeactivated(org.eclipse.ui.IWorkbenchPart) */ public void partDeactivated(IWorkbenchPart part) { fActivePart= null; } /** * @see IPartListener#partOpened(org.eclipse.ui.IWorkbenchPart) */ public void partOpened(IWorkbenchPart part) { } /** * Handles the activation triggering a element state check in the editor. */ private void handleActivation() { if (fIsHandlingActivation) return; if (fActivePart == CSSEditor.this) { fIsHandlingActivation= true; try { safelySanityCheckState(getEditorInput()); } finally { fIsHandlingActivation= false; } } } /** * @see org.eclipse.ui.IWindowListener#windowActivated(org.eclipse.ui.IWorkbenchWindow) */ public void windowActivated(IWorkbenchWindow window) { if (window == getEditorSite().getWorkbenchWindow()) { /* * Workaround for problem described in * http://dev.eclipse.org/bugs/show_bug.cgi?id=11731 * Will be removed when SWT has solved the problem. */ window.getShell().getDisplay().asyncExec(new Runnable() { public void run() { handleActivation(); } }); } } /** * @see org.eclipse.ui.IWindowListener#windowDeactivated(org.eclipse.ui.IWorkbenchWindow) */ public void windowDeactivated(IWorkbenchWindow window) { } /** * @see org.eclipse.ui.IWindowListener#windowClosed(org.eclipse.ui.IWorkbenchWindow) */ public void windowClosed(IWorkbenchWindow window) { } /** * @see org.eclipse.ui.IWindowListener#windowOpened(org.eclipse.ui.IWorkbenchWindow) */ public void windowOpened(IWorkbenchWindow window) { } } /** * The editor's activation listener. */ private ActivationListener fActivationListener; private boolean isDisposing = false; /** * CSSEditor */ public CSSEditor() { super(); addPluginToPreferenceStore(CSSPlugin.getDefault()); } /** * @see com.aptana.ide.editors.unified.UnifiedEditor#createLocalContributor() */ protected IUnifiedEditorContributor createLocalContributor() { return new CSSContributor(); } /** * @see com.aptana.ide.editors.unified.UnifiedEditor#getFileServiceFactory() */ public IFileServiceFactory getFileServiceFactory() { return CSSFileServiceFactory.getInstance(); } /** * @see com.aptana.ide.editors.unified.UnifiedEditor#getContextAwareness() */ public IContextAwareness getContextAwareness() { return CSSContextAwareness.getInstance(this); } /** * @see com.aptana.ide.editors.unified.UnifiedEditor#getDefaultFileExtension() */ public String getDefaultFileExtension() { return "css"; //$NON-NLS-1$ } /** * @see com.aptana.ide.editors.unified.UnifiedEditor#init(org.eclipse.ui.IEditorSite, org.eclipse.ui.IEditorInput) */ public void init(IEditorSite site, IEditorInput input) throws PartInitException { super.init(site, input); fActivationListener= new ActivationListener(site.getWorkbenchWindow().getPartService()); } /** * @see org.eclipse.ui.IWorkbenchPart#dispose() */ public void dispose() { if (isDisposing) { return; } isDisposing = true; if (fActivationListener != null) { fActivationListener.dispose(); fActivationListener= null; } super.dispose(); } public File getTempFile() { IEditorInput in = this.getEditorInput(); File outFile = null; if (in instanceof FileEditorInput) { IFile file = ((FileEditorInput) this.getEditorInput()).getFile(); IPath path = CoreUIUtils.getPathOfIFileLocation(file); if (path != null) { File f = path.makeAbsolute().toFile(); String location = getTempFileLocation(f, file.getName() + ".html"); //$NON-NLS-1$ outFile = new File(location); } } else if (in instanceof NonExistingFileEditorInput) { NonExistingFileEditorInput nin = (NonExistingFileEditorInput) in; IPath path = nin.getPath(nin); String spath = path.toOSString(); File f = new File(spath); String location = getTempFileLocation(f, path.lastSegment() + ".html"); //$NON-NLS-1$ outFile = new File(location); } else if (in instanceof IPathEditorInput) { IPathEditorInput pin = (IPathEditorInput) in; File path = pin.getPath().toFile(); String location = getTempFileLocation(path, pin.getName() + ".html"); //$NON-NLS-1$ outFile = new File(location); } else if (in instanceof IURIEditorInput) { URI uri = ((IURIEditorInput) in).getURI(); String location; if ("file".equals(uri.getScheme())) { location = getTempFileLocation(new File(uri), Path.fromPortableString(uri.getPath()).lastSegment()); } else { location = getTempFileLocation(null, Path.fromPortableString(uri.getPath()).lastSegment()); } outFile = new File(location); } if (outFile != null) { outFile.deleteOnExit(); } return outFile; } /** * The location of the temp file * * @param file * @param name * @return String */ public String getTempFileLocation(File file, String name) { if (CSSPlugin.getDefault().getPreferenceStore().getBoolean(IPreferenceConstants.USE_TEMP_FILES_FOR_PREVIEW)) { if (file != null) { file = file.getParentFile(); } else { try { return File.createTempFile(".tmp_" + name, "~").getAbsolutePath(); } catch (IOException e) { return null; } } return file + File.separator + ".tmp_" + name + ((int) (Math.random() * 100000)) + "~"; //$NON-NLS-1$ //$NON-NLS-2$ } else { return FileUtils.systemTempDir + File.separator + ".tmp_" + name + "~"; //$NON-NLS-1$ //$NON-NLS-2$ } } /** * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#collectContextMenuPreferencePages() */ protected String[] collectContextMenuPreferencePages() { return new String[] { "com.aptana.ide.editor.css.preferences.GeneralPreferencePage", //$NON-NLS-1$ "com.aptana.ide.editor.css.preferences.ColorizationPreferencePage", //$NON-NLS-1$ "com.aptana.ide.editor.css.preferences.FoldingPreferencePage", //$NON-NLS-1$ "com.aptana.ide.editor.css.preferences.ProblemsPreferencePage", //$NON-NLS-1$ "com.aptana.ide.editor.css.preferences.PreviewPreferencePage", //$NON-NLS-1$ "com.aptana.ide.editor.css.preferences.FormattingPreferencePage", //$NON-NLS-1$ "com.aptana.ide.editor.css.preferences.CodeAssistPreferencePage", //$NON-NLS-1$ "com.aptana.ide.editor.css.preferences.TypingPreferencePage", //$NON-NLS-1$ "org.eclipse.ui.preferencePages.GeneralTextEditor", //$NON-NLS-1$ "org.eclipse.ui.editors.preferencePages.Annotations", //$NON-NLS-1$ "org.eclipse.ui.editors.preferencePages.QuickDiff", //$NON-NLS-1$ "org.eclipse.ui.editors.preferencePages.Accessibility", //$NON-NLS-1$ "org.eclipse.ui.editors.preferencePages.Spelling", //$NON-NLS-1$ "org.eclipse.ui.editors.preferencePages.LinkedModePreferencePage", //$NON-NLS-1$ }; } /** * isNewInput * * @param input * @return boolean */ protected boolean isNewInput(IEditorInput input) { CSSFileInfo cuInfo = getCSSFileInfo(input); if (cuInfo == null) { throw new RuntimeException(Messages.CSSEditor_cuInfo_Null_At_DoSetInput); } CSSDocumentProvider dp = (CSSDocumentProvider) getDocumentProvider(); // Get document from input IDocument document = dp.getDocument(input); DocumentSourceProvider provider = new DocumentSourceProvider(document, input); if (provider == null) { throw new RuntimeException(Messages.CSSEditor_Provider_Null); } return (cuInfo.sourceProvider == null || cuInfo.sourceProvider.equals(provider) == false); } private CSSFileInfo getCSSFileInfo(IEditorInput input) { CSSDocumentProvider dp = (CSSDocumentProvider) getDocumentProvider(); if (dp == null) { throw new RuntimeException(Messages.CSSEditor_Document_Provier_Null); } return (CSSFileInfo) dp.getFileInfoPublic(input); } /** * Updates the file information * * @param input * @param provider * @param document */ protected void updateFileInfo(IEditorInput input, DocumentSourceProvider provider, IDocument document) { super.updateFileInfo(input, provider, document); if (isNewInput(input)) { // save reference to provider getCSSFileInfo(input).sourceProvider = provider; } } /** * @see com.aptana.ide.editors.unified.UnifiedEditor#createDocumentProvider() */ public IDocumentProvider createDocumentProvider() { return CSSDocumentProvider.getInstance(); } }