/** * 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.editors.untitled; import java.io.File; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IFileEditorInput; import org.eclipse.ui.IPathEditorInput; import org.eclipse.ui.IURIEditorInput; import org.eclipse.ui.editors.text.TextEditor; import org.eclipse.ui.internal.editors.text.NonExistingFileEditorInput; import org.eclipse.ui.texteditor.IDocumentProvider; import com.aptana.ide.core.StringUtils; import com.aptana.ide.core.ui.CoreUIUtils; /** * The base text editor from which other editors are derived. This class manages the Save As of different file types * (external or project files). The save operation is then delegated to the document provider, which is the * UnifiedDocumentProvider, which is implemented in BaseDocumentProvider * * @author Ingo Muschenetz */ public class BaseTextEditor extends TextEditor { private String directoryHint; /** * @see org.eclipse.ui.texteditor.AbstractTextEditor#performSave(boolean, org.eclipse.core.runtime.IProgressMonitor) */ protected void performSave(boolean overwrite, IProgressMonitor progressMonitor) { // TODO Auto-generated method stub super.performSave(overwrite, progressMonitor); onSaveComplete(); } /** * Hook to allow editors to deal with save operation being completed. */ protected void onSaveComplete() { } /** * The <code>TextEditor</code> implementation of this <code>AbstractTextEditor</code> method asks the user for * the workspace path of a file resource and saves the document there. * * @param progressMonitor * the progress monitor to be used */ protected void performSaveAs(IProgressMonitor progressMonitor) { IEditorInput input = getEditorInput(); String oldPath = CoreUIUtils.getPathFromEditorInput(input); File newFile = null; File oldFile = oldPath == null ? null : new File(oldPath); IFile file = (input instanceof IFileEditorInput) ? ((IFileEditorInput) input).getFile() : null; if (file != null) { super.performSaveAs(progressMonitor); String newPath = CoreUIUtils.getPathFromEditorInput(getEditorInput()); newFile = new File(newPath); } else { // the file being edited is not part of the project, so save the file as an external // file. newFile = doExternalSaveAs(progressMonitor); } onSaveAsComplete(oldFile, newFile); } /** * Hook to allow editors to deal with save as operation being completed. * * @param oldFile * @param newFile * The new file being saved */ protected void onSaveAsComplete(final File oldFile, final File newFile) { } private File doExternalSaveAs(IProgressMonitor progressMonitor) { Shell shell = getSite().getShell(); IDocumentProvider provider = getDocumentProvider(); IEditorInput input = getEditorInput(); FileDialog fileDialog = new FileDialog(shell, SWT.SAVE); String fileName = getDefaultSaveAsFile(); fileDialog.setFileName(getBaseFilename(fileName)); FileDialogFilterInfo filterInfo = getFileDialogFilterInformation(fileName); String [] fileExtensions = filterInfo.getFilterExtensions(); if (fileExtensions != null && fileExtensions.length >0) { fileDialog.setFilterExtensions(fileExtensions); fileDialog.setFilterNames(filterInfo.getFilterNames()); } // [IM] This appears to have no effect on OSX. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=101948 if (directoryHint != null) { File f = new File(directoryHint); if (f.exists()) { fileDialog.setFilterPath(directoryHint); } } String text = fileDialog.open(); if (text == null) { if (progressMonitor != null) { progressMonitor.setCanceled(true); } return null; } File file = new File(text); final IEditorInput newInput = CoreUIUtils.createJavaFileEditorInput(file); boolean success = false; try { provider.aboutToChange(newInput); provider.saveDocument(progressMonitor, newInput, provider.getDocument(input), true); success = true; } catch (CoreException x) { IStatus status = x.getStatus(); if (status == null || status.getSeverity() != IStatus.CANCEL) { String title = Messages.BaseTextEditor_SaveFileError; String msg = StringUtils.format(Messages.BaseTextEditor_ErrorSaving, new Object[] { x.getMessage() }); if (status != null) { switch (status.getSeverity()) { case IStatus.INFO: MessageDialog.openInformation(shell, title, msg); break; case IStatus.WARNING: MessageDialog.openWarning(shell, title, msg); break; default: MessageDialog.openError(shell, title, msg); } } else { MessageDialog.openError(shell, title, msg); } } } finally { provider.changed(newInput); if (success) { setInput(newInput); } } if (progressMonitor != null) { progressMonitor.setCanceled(!success); } if (success) { return file; } else { return null; } } /** * Returns name and extension filters for display in file dialog * @param fileName * @return FileDialogFilterInfo */ protected FileDialogFilterInfo getFileDialogFilterInformation(String fileName) { FileDialogFilterInfo filterInfo = null; String fileExtension = getFileExtension(fileName); if(!fileExtension.equals(StringUtils.EMPTY)) { filterInfo = new FileDialogFilterInfo(); filterInfo.setFilterExtensions(new String[] { "*" + fileExtension, "All Files (*.*)" }); //$NON-NLS-1$ //$NON-NLS-2$ filterInfo.setFilterNames(new String[] { "*" + fileExtension, Messages.BaseTextEditor_AllFiles }); //$NON-NLS-1$ } else { filterInfo = new FileDialogFilterInfo(); filterInfo.setFilterExtensions(new String[] { "*.*" }); //$NON-NLS-1$ filterInfo.setFilterNames(new String[] { Messages.BaseTextEditor_AllFiles }); //$NON-NLS-1$ } return filterInfo; } /** * Returns the default file. * * @return The path to the newly saved file */ protected String getDefaultSaveAsFile() { IEditorInput input = this.getEditorInput(); if (input instanceof IFileEditorInput) { IFileEditorInput fileInput = (IFileEditorInput) input; return fileInput.getFile().getLocation().toOSString(); } else if (input instanceof IPathEditorInput) { IPathEditorInput pathInput = (IPathEditorInput) input; return pathInput.getPath().toOSString(); } else if (input instanceof IURIEditorInput) { IURIEditorInput uriInput = (IURIEditorInput) input; return uriInput.getURI().getPath(); } else if (input instanceof NonExistingFileEditorInput) { NonExistingFileEditorInput nonExist = (NonExistingFileEditorInput) input; IPath path = nonExist.getPath(input); String fileName = getTitle(); String lastSegment = path.lastSegment(); int extIndex = lastSegment.lastIndexOf("."); //$NON-NLS-1$ if (extIndex != -1) { fileName = fileName + lastSegment.substring(extIndex); } return fileName; } return null; } /** * Returns the extension of a file * * @param fileName * @return String */ protected String getFileExtension(String fileName) { String lastSegment = fileName; int extIndex = lastSegment.lastIndexOf("."); //$NON-NLS-1$ if (extIndex != -1) { return lastSegment.substring(extIndex); } else { return StringUtils.EMPTY; } } private static String getBaseFilename(String filepath) { int index = filepath.lastIndexOf(File.separator); return (index < 0) ? filepath : filepath.substring(index + 1); } /** * getParentDirectoryHint * * @return String */ public String getParentDirectoryHint() { return directoryHint; } /** * setParentDirectoryHint * * @param hint */ public void setParentDirectoryHint(String hint) { directoryHint = hint; } /** * Holds information used for File Save As dialog box * @author Samir * */ protected class FileDialogFilterInfo { private String[] filterNames; private String[] filterExtensions; /** * Default construction is public * */ public FileDialogFilterInfo() { } /** * @return Array of filter extensions */ public String[] getFilterExtensions() { return filterExtensions; } /** * @param filterExtensions */ public void setFilterExtensions(String[] filterExtensions) { this.filterExtensions = filterExtensions; } /** * @return array of filter names; */ public String[] getFilterNames() { return filterNames; } /** * @param filterNames */ public void setFilterNames(String[] filterNames) { this.filterNames = filterNames; } } }