diff options
Diffstat (limited to 'org.eclipse.ui.editors/src/org')
23 files changed, 3196 insertions, 0 deletions
diff --git a/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/DefaultEncodingSupport.java b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/DefaultEncodingSupport.java new file mode 100644 index 00000000000..d6e8b2cee97 --- /dev/null +++ b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/DefaultEncodingSupport.java @@ -0,0 +1,219 @@ +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: + IBM Corporation - Initial implementation +**********************************************************************/ + +package org.eclipse.ui.editors.text; + + +import java.io.CharConversionException; +import java.io.UnsupportedEncodingException; +import java.text.MessageFormat; + +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Preferences; + +import org.eclipse.ui.texteditor.IDocumentProvider; +import org.eclipse.ui.texteditor.StatusTextEditor; + + + +/** + * The standard implementation of <code>IEncodingSupport</code>. + * @since 2.0 + */ +public class DefaultEncodingSupport implements IEncodingSupport { + + /** Internal property change listener. */ + private Preferences.IPropertyChangeListener fPropertyChangeListener; + /** The editor this support is associated with. */ + private StatusTextEditor fTextEditor; + /** The action group of this support. */ + private EncodingActionGroup fEncodingActionGroup; + + /** + * Creates a new encoding support. + */ + public DefaultEncodingSupport() { + super(); + } + + /** + * Associates this encoding support to the given text editor and initializes this encoding. + * + * @param textEditor the editor + */ + public void initialize(StatusTextEditor textEditor) { + + fTextEditor= textEditor; + + fPropertyChangeListener= new Preferences.IPropertyChangeListener() { + public void propertyChange(Preferences.PropertyChangeEvent e) { + if (ResourcesPlugin.PREF_ENCODING.equals(e.getProperty())) + setEncoding(null, false); + } + }; + + Preferences p= ResourcesPlugin.getPlugin().getPluginPreferences(); + p.addPropertyChangeListener(fPropertyChangeListener); + + fEncodingActionGroup= new EncodingActionGroup(fTextEditor); + fEncodingActionGroup.update(); + } + + /** + * Disposes this encoding support. + */ + public void dispose() { + Preferences p= ResourcesPlugin.getPlugin().getPluginPreferences(); + p.removePropertyChangeListener(fPropertyChangeListener); + + fEncodingActionGroup.dispose(); + fEncodingActionGroup= null; + + fTextEditor= null; + } + + /** + * Resets this encoding support. Should be called if, e.g., the input element of the + * associated editor changed. + */ + public void reset() { + fEncodingActionGroup.update(); + } + + /** + * Sets the encoding of the editor's input to the given value. If <code>overwrite</code> is + * <code>true</code> the value is set even if the encoding is already set. + * + * @param encoding the new encoding + * @param overwrite <code>true</code> if current encoding should be overwritten + */ + protected void setEncoding(String encoding, boolean overwrite) { + + // http://dev.eclipse.org/bugs/show_bug.cgi?id=19206 + if (fTextEditor.isDirty()) + return; + + String internal= encoding == null ? "" : encoding; //$NON-NLS-1$ + + IDocumentProvider p= fTextEditor.getDocumentProvider(); + if (p instanceof IStorageDocumentProvider) { + IStorageDocumentProvider provider= (IStorageDocumentProvider) p; + String current= provider.getEncoding(fTextEditor.getEditorInput()); + + boolean apply= (current != null && encoding == null) ? overwrite : !internal.equals(current); + if (apply) { + + provider.setEncoding(fTextEditor.getEditorInput(), encoding); + fTextEditor.doRevertToSaved(); + fTextEditor.updatePartControl(fTextEditor.getEditorInput()); + + fEncodingActionGroup.update(); + } + } + } + + /* + * @see IEncodingSupport#setEncoding(String) + */ + public void setEncoding(String encoding) { + setEncoding(encoding, true); + } + + /* + * @see IEncodingSupport#getEncoding() + */ + public String getEncoding() { + IDocumentProvider p= fTextEditor.getDocumentProvider(); + if (p instanceof IStorageDocumentProvider) { + IStorageDocumentProvider provider= (IStorageDocumentProvider) p; + return provider.getEncoding(fTextEditor.getEditorInput()); + } + return null; + } + + /* + * @see IEncodingSupport#getDefaultEncoding() + */ + public String getDefaultEncoding() { + IDocumentProvider p= fTextEditor.getDocumentProvider(); + if (p instanceof IStorageDocumentProvider) { + IStorageDocumentProvider provider= (IStorageDocumentProvider) p; + return provider.getDefaultEncoding(); + } + return null; + } + + /** + * Returns a status header for the given status. + * @param status the status + * @return a status header for the given status. + */ + public String getStatusHeader(IStatus status) { + Throwable t= status.getException(); + + if (t instanceof CharConversionException) + return TextEditorMessages.getString("Editor.error.unreadable_encoding.header"); //$NON-NLS-1$ + + if (t instanceof UnsupportedEncodingException) + return TextEditorMessages.getString("Editor.error.unsupported_encoding.header"); //$NON-NLS-1$ + + return null; + } + + /** + * Returns a banner for the given status + * @param status the status + * @return a banner for the given status. + */ + public String getStatusBanner(IStatus status) { + Throwable t= status.getException(); + + if (t instanceof CharConversionException) + return TextEditorMessages.getString("Editor.error.unreadable_encoding.banner"); //$NON-NLS-1$ + + if (t instanceof UnsupportedEncodingException) + return TextEditorMessages.getString("Editor.error.unsupported_encoding.banner"); //$NON-NLS-1$ + + return null; + + } + + /** + * Returns a status message for the given status indicating encoding problems or <code>null</code> otherwise. + * + * @param status the status + * @return a status message indicating encoding problems + */ + public String getStatusMessage(IStatus status) { + Throwable t= status.getException(); + if (t instanceof CharConversionException || t instanceof UnsupportedEncodingException) { + + String encoding= getEncoding(); + if (encoding == null) + encoding= getDefaultEncoding(); + + if (t instanceof CharConversionException) { + if (encoding != null) + return MessageFormat.format(TextEditorMessages.getString("Editor.error.unreadable_encoding.message_arg"), new Object[] { encoding }); //$NON-NLS-1$ + return TextEditorMessages.getString("Editor.error.unreadable_encoding.message"); //$NON-NLS-1$ + } + + if (t instanceof UnsupportedEncodingException) { + if (encoding != null) + return MessageFormat.format(TextEditorMessages.getString("Editor.error.unsupported_encoding.message_arg"), new Object[] { encoding }); //$NON-NLS-1$ + return TextEditorMessages.getString("Editor.error.unsupported_encoding.message"); //$NON-NLS-1$ + } + } + + return null; + } +} diff --git a/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/EncodingActionGroup.java b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/EncodingActionGroup.java new file mode 100644 index 00000000000..399dbb12460 --- /dev/null +++ b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/EncodingActionGroup.java @@ -0,0 +1,383 @@ +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: + IBM Corporation - Initial implementation +**********************************************************************/ + +package org.eclipse.ui.editors.text; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.ResourceBundle; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.dialogs.IInputValidator; +import org.eclipse.jface.dialogs.InputDialog; + +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.IWorkbenchActionConstants; +import org.eclipse.ui.actions.ActionGroup; +import org.eclipse.ui.texteditor.ITextEditor; +import org.eclipse.ui.texteditor.IUpdate; +import org.eclipse.ui.texteditor.ResourceAction; +import org.eclipse.ui.texteditor.RetargetTextEditorAction; +import org.eclipse.ui.texteditor.TextEditorAction; + + +/** + * Action group for encoding actions. + * @since 2.0 + */ +public class EncodingActionGroup extends ActionGroup { + + /** + * Action for setting the encoding of the editor to the value this action has + * been initialized with. + */ + static class PredefinedEncodingAction extends TextEditorAction { + + /** The target encoding of this action. */ + private String fEncoding; + /** The action label */ + private String fLabel; + /** Indicates whether the target encoding is the default encoding. */ + private boolean fIsDefault; + + /** + * Creates a new action for the given specification. + * + * @param bundle the resource bundle + * @param prefix the prefix for lookups from the resource bundle + * @param encoding the target encoding + * @param editor the target editor + */ + public PredefinedEncodingAction(ResourceBundle bundle, String prefix, String encoding, ITextEditor editor) { + super(bundle, prefix, editor); + fEncoding= encoding; + if (prefix == null) + setText(encoding); + fLabel= getText(); + } + + /** + * Creates a new action for the given specification. + * + * @param bundle the resource bundle + * @param encoding the target encoding + * @param editor the target editor + */ + public PredefinedEncodingAction(ResourceBundle bundle, String encoding, ITextEditor editor) { + super(bundle, null, editor); + fEncoding= encoding; + setText(encoding); + fLabel= getText(); + } + + /** + * Returns the encoding support of the action's editor. + * + * @return the encoding support of the action's editor + */ + private IEncodingSupport getEncodingSupport() { + ITextEditor editor= getTextEditor(); + if (editor != null) + return (IEncodingSupport) editor.getAdapter(IEncodingSupport.class); + return null; + } + + /* + * @see IAction#run() + */ + public void run() { + IEncodingSupport s= getEncodingSupport(); + if (s != null) + s.setEncoding(fIsDefault ? null : fEncoding); + } + + /** + * Returns the encoding currently used in the given editor. + * + * @param editor the editor + * @return the encoding currently used in the given editor + */ + private String getEncoding(ITextEditor editor) { + IEncodingSupport s= getEncodingSupport(); + if (s != null) + return s.getEncoding(); + return null; + } + + /** + * Returns the default encoding for the given editor. + * + * @param editor the editor + * @return the default encoding for the given editor + */ + private String getDefaultEncoding(ITextEditor editor) { + IEncodingSupport s= getEncodingSupport(); + if (s != null) + return s.getDefaultEncoding(); + return null; + } + + /* + * @see IUpdate#update() + */ + public void update() { + + if (fEncoding == null) { + setEnabled(false); + return; + } + + ITextEditor editor= getTextEditor(); + if (editor == null) { + setEnabled(false); + return; + } + + // update label + String encoding= getDefaultEncoding(editor); + if (encoding != null) { + fIsDefault= fEncoding.equals(encoding); + setText(fIsDefault ? fLabel + DEFAULT_SUFFIX : fLabel); + } + + // update enable state + if (editor.isDirty()) { + setEnabled(false); + } else { + String current= getEncoding(editor); + if (fIsDefault) + setEnabled(current != null); + else + setEnabled(!fEncoding.equals(current)); + } + } + }; + + /** + * Sets the encoding of an editor to the value that has interactively been defined. + */ + static class CustomEncodingAction extends TextEditorAction { + + + /* + * @see org.eclipse.ui.texteditor.TextEditorAction#TextEditorAction(ResourceBundle, String, ITextEditor) + */ + protected CustomEncodingAction(ResourceBundle bundle, String prefix, ITextEditor editor) { + super(bundle, prefix, editor); + } + + /* + * @see IUpdate#update() + */ + public void update() { + ITextEditor editor= getTextEditor(); + setEnabled(editor != null && !editor.isDirty()); + } + + /* + * @see IAction#run() + */ + public void run() { + + ITextEditor editor= getTextEditor(); + if (editor == null) + return; + + String title= TextEditorMessages.getString("Editor.ConvertEncoding.Custom.dialog.title"); //$NON-NLS-1$ + String message= TextEditorMessages.getString("Editor.ConvertEncoding.Custom.dialog.message"); //$NON-NLS-1$ + IInputValidator inputValidator = new IInputValidator() { + public String isValid(String newText) { + return (newText == null || newText.length() == 0) ? " " : null; //$NON-NLS-1$ + } + }; + + InputDialog d= new InputDialog(editor.getSite().getShell(), title, message, "", inputValidator); //$NON-NLS-1$ + if (d.open() == d.OK) { + IEncodingSupport s= (IEncodingSupport) editor.getAdapter(IEncodingSupport.class); + if (s != null) + s.setEncoding(d.getValue()); + } + } + }; + + + /** Suffix added to the default encoding action */ + private static final String DEFAULT_SUFFIX= " " + TextEditorMessages.getString("Editor.ConvertEncoding.default_suffix"); //$NON-NLS-1$ //$NON-NLS-2$ + + /** List of predefined encodings */ + private static final String[][] ENCODINGS; + + /** The default encoding */ + private static final String SYSTEM_ENCODING; + + /** + * Initializer: computes the set of predefined encoding actions. + */ + static { + + String[][] encodings= { + { IEncodingActionsConstants.US_ASCII, IEncodingActionsHelpContextIds.US_ASCII, IEncodingActionsDefinitionIds.US_ASCII }, + { IEncodingActionsConstants.ISO_8859_1, IEncodingActionsHelpContextIds.ISO_8859_1, IEncodingActionsDefinitionIds.ISO_8859_1 }, + { IEncodingActionsConstants.UTF_8, IEncodingActionsHelpContextIds.UTF_8, IEncodingActionsDefinitionIds.UTF_8 }, + { IEncodingActionsConstants.UTF_16BE, IEncodingActionsHelpContextIds.UTF_16BE, IEncodingActionsDefinitionIds.UTF_16BE }, + { IEncodingActionsConstants.UTF_16LE, IEncodingActionsHelpContextIds.UTF_16LE, IEncodingActionsDefinitionIds.UTF_16LE }, + { IEncodingActionsConstants.UTF_16, IEncodingActionsHelpContextIds.UTF_16, IEncodingActionsDefinitionIds.UTF_16 } + }; + + String system= System.getProperty("file.encoding"); //$NON-NLS-1$ + if (system != null) { + + int i; + for (i= 0; i < encodings.length; i++) { + if (encodings[i][0].equals(system)) + break; + } + + if (i != encodings.length) { + // bring default in first position + String[] s= encodings[i]; + encodings[i]= encodings[0]; + encodings[0]= s; + // forget default encoding as it's already in the list + system= null; + } + } + + SYSTEM_ENCODING= system; + ENCODINGS= encodings; + } + + + + /** List of encoding actions of this group */ + private List fRetargetActions= new ArrayList(); + + /** + * Creates a new encoding action group for an action bar contributor. + */ + public EncodingActionGroup() { + + ResourceBundle b= TextEditorMessages.getResourceBundle(); + + if (SYSTEM_ENCODING != null) + fRetargetActions.add(new RetargetTextEditorAction(b, "Editor.ConvertEncoding.System.", IEncodingActionsConstants.SYSTEM)); //$NON-NLS-1$ + + for (int i= 0; i < ENCODINGS.length; i++) + fRetargetActions.add(new RetargetTextEditorAction(b, "Editor.ConvertEncoding." + ENCODINGS[i][0] + ".", ENCODINGS[i][0])); //$NON-NLS-1$ //$NON-NLS-2$ + + fRetargetActions.add(new RetargetTextEditorAction(b, "Editor.ConvertEncoding.Custom.", IEncodingActionsConstants.CUSTOM)); //$NON-NLS-1$ + } + + /* + * @see ActionGroup#fillActionBars(IActionBars) + */ + public void fillActionBars(IActionBars actionBars) { + IMenuManager menuManager= actionBars.getMenuManager(); + IMenuManager editMenu= menuManager.findMenuUsingPath(IWorkbenchActionConstants.M_EDIT); + if (editMenu != null) { + MenuManager subMenu= new MenuManager(TextEditorMessages.getString("Editor.ConvertEncoding.submenu.label")); //$NON-NLS-1$ + + Iterator e= fRetargetActions.iterator(); + while (e.hasNext()) + subMenu.add((IAction) e.next()); + + editMenu.add(subMenu); + } + } + + /** + * Retargets this action group to the given editor. + * + * @param editor the target editor + */ + public void retarget(ITextEditor editor) { + Iterator e= fRetargetActions.iterator(); + while (e.hasNext()) { + RetargetTextEditorAction a= (RetargetTextEditorAction) e.next(); + a.setAction(editor == null ? null : editor.getAction(a.getId())); + } + } + + + //------------------------------------------------------------------------------------------ + + + /** Text editor this group is associated with */ + private ITextEditor fTextEditor; + + /** + * Creates a new encoding action group for the given editor + * + * @param editor the editor + */ + public EncodingActionGroup(ITextEditor editor) { + + fTextEditor= editor; + ResourceBundle b= TextEditorMessages.getResourceBundle(); + + ResourceAction a; + if (SYSTEM_ENCODING != null) { + a= new PredefinedEncodingAction(b, SYSTEM_ENCODING, editor); + a.setHelpContextId(IEncodingActionsHelpContextIds.SYSTEM); + a.setActionDefinitionId(IEncodingActionsDefinitionIds.SYSTEM); + editor.setAction(IEncodingActionsConstants.SYSTEM, a); + } + + for (int i= 0; i < ENCODINGS.length; i++) { + a= new PredefinedEncodingAction(b, "Editor.ConvertEncoding." + ENCODINGS[i][0] + ".", ENCODINGS[i][0], editor); //$NON-NLS-1$ //$NON-NLS-2$ + a.setHelpContextId( ENCODINGS[i][1]); + a.setActionDefinitionId( ENCODINGS[i][2]); + editor.setAction(ENCODINGS[i][0], a); + } + + a= new CustomEncodingAction(b, "Editor.ConvertEncoding." + IEncodingActionsConstants.CUSTOM + ".", editor); //$NON-NLS-1$ //$NON-NLS-2$ + a.setHelpContextId(IEncodingActionsHelpContextIds.CUSTOM); + a.setActionDefinitionId(IEncodingActionsDefinitionIds.CUSTOM); + editor.setAction(IEncodingActionsConstants.CUSTOM, a); + } + + /** + * Updates all actions of this action group. + */ + public void update() { + + IAction a= fTextEditor.getAction(IEncodingActionsConstants.SYSTEM); + if (a instanceof IUpdate) + ((IUpdate) a).update(); + + for (int i= 0; i < ENCODINGS.length; i++) { + a= fTextEditor.getAction(ENCODINGS[i][0]); + if (a instanceof IUpdate) + ((IUpdate) a).update(); + } + + a= fTextEditor.getAction(IEncodingActionsConstants.CUSTOM); + if (a instanceof IUpdate) + ((IUpdate) a).update(); + } + + /* + * @see ActionGroup#dispose() + */ + public void dispose() { + if (fTextEditor != null) { + fTextEditor.setAction(IEncodingActionsConstants.SYSTEM, null); + for (int i= 0; i < ENCODINGS.length; i++) + fTextEditor.setAction(ENCODINGS[i][0], null); + fTextEditor.setAction(IEncodingActionsConstants.CUSTOM, null); + + fTextEditor= null; + } + } +} diff --git a/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/FileDocumentProvider.java b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/FileDocumentProvider.java new file mode 100644 index 00000000000..70f7e6a8d1b --- /dev/null +++ b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/FileDocumentProvider.java @@ -0,0 +1,670 @@ +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: + IBM Corporation - Initial implementation +**********************************************************************/ + +package org.eclipse.ui.editors.text; + + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Iterator; + +import org.eclipse.swt.widgets.Display; + +import org.eclipse.core.resources.IFile; +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.IResourceStatus; +import org.eclipse.core.resources.IWorkspace; +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.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubProgressMonitor; + +import org.eclipse.jface.text.Document; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.source.IAnnotationModel; + +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IFileEditorInput; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.dialogs.ContainerGenerator; +import org.eclipse.ui.part.FileEditorInput; +import org.eclipse.ui.texteditor.IElementStateListener; +import org.eclipse.ui.texteditor.ResourceMarkerAnnotationModel; + + + +/** + * Shareable document provider specialized for file resources (<code>IFile</code>).<p> + * This class may be instantiated or be subclassed. + */ +public class FileDocumentProvider extends StorageDocumentProvider { + + + /** + * Runnable encapsulating an element state change. This runnable ensures + * that a element change failed message is sent out to the element state listeners + * in case an exception occurred. + * @since 2.0 + */ + protected class SafeChange implements Runnable { + + /** The input that changes. */ + private IFileEditorInput fInput; + + /** + * Creates a new safe runnable for the given input. + * @param input the input + */ + public SafeChange(IFileEditorInput input) { + fInput= input; + } + + /** + * Subclass responsibility. + * @param input the input + * @exception Exception in case of error + */ + protected void execute(IFileEditorInput input) throws Exception { + } + + /* + * @see java.lang.Runnable#run() + * @since 2.0 + */ + public void run() { + + if (getElementInfo(fInput) == null) { + fireElementStateChangeFailed(fInput); + return; + } + + try { + execute(fInput); + } catch (Exception e) { + fireElementStateChangeFailed(fInput); + } + } + }; + + + /** + * Synchronizes the document with external resource changes. + */ + protected class FileSynchronizer implements IResourceChangeListener, IResourceDeltaVisitor { + + /** The file editor input */ + protected IFileEditorInput fFileEditorInput; + + /** + * Creates a new file synchronizer. Is not yet installed on a resource. + * @param fileEditorInput the editor input to be synchronized + */ + public FileSynchronizer(IFileEditorInput fileEditorInput) { + fFileEditorInput= fileEditorInput; + }; + + /** + * Creates a new file synchronizer. Is not yet installed on a resource. + * @param fileEditorInput the editor input to be synchronized + * @deprecated use FileSynchronizer(IFileEditorInput) + */ + public FileSynchronizer(FileEditorInput fileEditorInput) { + fFileEditorInput= fileEditorInput; + }; + + /** + * Returns the file wrapped by the file editor input. + * @return the file wrapped by the editor input associated with that synchronizer + */ + protected IFile getFile() { + return fFileEditorInput.getFile(); + } + + /** + * Installs the synchronizer on the input's file. + */ + public void install() { + getFile().getWorkspace().addResourceChangeListener(this); + } + + /** + * Uninstalls the synchronizer from the input's file. + */ + public void uninstall() { + getFile().getWorkspace().removeResourceChangeListener(this); + } + + /* + * @see IResourceChangeListener#resourceChanged(IResourceChangeEvent) + */ + public void resourceChanged(IResourceChangeEvent e) { + IResourceDelta delta= e.getDelta(); + try { + if (delta != null) + delta.accept(this); + } catch (CoreException x) { + handleCoreException(x, TextEditorMessages.getString("FileDocumentProvider.resourceChanged")); //$NON-NLS-1$ + } + } + + /* + * @see IResourceDeltaVisitor#visit(IResourceDelta) + */ + public boolean visit(IResourceDelta delta) throws CoreException { + + if (delta != null && getFile().equals(delta.getResource())) { + + Runnable runnable= null; + + switch (delta.getKind()) { + case IResourceDelta.CHANGED: + if ((IResourceDelta.CONTENT & delta.getFlags()) != 0) { + FileInfo info= (FileInfo) getElementInfo(fFileEditorInput); + if (!info.fCanBeSaved && computeModificationStamp(getFile()) != info.fModificationStamp) { + runnable= new SafeChange(fFileEditorInput) { + protected void execute(IFileEditorInput input) throws Exception { + handleElementContentChanged(input); + } + }; + } + } + break; + case IResourceDelta.REMOVED: + if ((IResourceDelta.MOVED_TO & delta.getFlags()) != 0) { + final IPath path= delta.getMovedToPath(); + runnable= new SafeChange(fFileEditorInput) { + protected void execute(IFileEditorInput input) throws Exception { + handleElementMoved(input, path); + } + }; + } else { + FileInfo info= (FileInfo) getElementInfo(fFileEditorInput); + if (!info.fCanBeSaved) { + runnable= new SafeChange(fFileEditorInput) { + protected void execute(IFileEditorInput input) throws Exception { + handleElementDeleted(input); + } + }; + } + } + break; + } + + if (runnable != null) + update(runnable); + } + + return true; // because we are sitting on files anyway + } + + /** + * Posts the update code "behind" the running operation. + * + * @param runnable the update code + */ + protected void update(Runnable runnable) { + + if (runnable instanceof SafeChange) + fireElementStateChanging(fFileEditorInput); + + IWorkbench workbench= PlatformUI.getWorkbench(); + IWorkbenchWindow[] windows= workbench.getWorkbenchWindows(); + if (windows != null && windows.length > 0) { + Display display= windows[0].getShell().getDisplay(); + display.asyncExec(runnable); + } else { + runnable.run(); + } + } + }; + + + + /** + * Bundle of all required information to allow files as underlying document resources. + */ + protected class FileInfo extends StorageInfo { + + /** The file synchronizer */ + public FileSynchronizer fFileSynchronizer; + /** The time stamp at which this provider changed the file */ + public long fModificationStamp= IResource.NULL_STAMP; + + /** + * Creates a new file info. + * @param document the document + * @param model the annotation model + * @param fileSynchronizer the file synchronizer + */ + public FileInfo(IDocument document, IAnnotationModel model, FileSynchronizer fileSynchronizer) { + super(document, model); + fFileSynchronizer= fileSynchronizer; + } + }; + + + /** + * Creates a new document provider. + */ + public FileDocumentProvider() { + super(); + } + + /** + * Overrides <code>StorageDocumentProvider#setDocumentContent(IDocument, IEditorInput)</code>. + * @deprecated use file encoding based version + * @since 2.0 + */ + protected boolean setDocumentContent(IDocument document, IEditorInput editorInput) throws CoreException { + if (editorInput instanceof IFileEditorInput) { + IFile file= ((IFileEditorInput) editorInput).getFile(); + setDocumentContent(document, file.getContents(false)); + return true; + } + return super.setDocumentContent(document, editorInput); + } + + /* + * @see StorageDocumentProvider#setDocumentContent(IDocument, IEditorInput, String) + * @since 2.0 + */ + protected boolean setDocumentContent(IDocument document, IEditorInput editorInput, String encoding) throws CoreException { + if (editorInput instanceof IFileEditorInput) { + IFile file= ((IFileEditorInput) editorInput).getFile(); + setDocumentContent(document, file.getContents(false), encoding); + return true; + } + return super.setDocumentContent(document, editorInput, encoding); + } + + /* + * @see AbstractDocumentProvider#createAnnotationModel(Object) + */ + protected IAnnotationModel createAnnotationModel(Object element) throws CoreException { + if (element instanceof IFileEditorInput) { + IFileEditorInput input= (IFileEditorInput) element; + return new ResourceMarkerAnnotationModel(input.getFile()); + } + + return super.createAnnotationModel(element); + } + + /** + * Checks whether the given resource has been changed on the + * local file system by comparing the actual time stamp with the + * cached one. If the resource has been changed, a <code>CoreException</code> + * is thrown. + * + * @param cachedModificationStamp the chached modification stamp + * @param resource the resource to check + * @exception CoreException if resource has been changed on the file system + */ + protected void checkSynchronizationState(long cachedModificationStamp, IResource resource) throws CoreException { + if (cachedModificationStamp != computeModificationStamp(resource)) { + Status status= new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, IResourceStatus.OUT_OF_SYNC_LOCAL, TextEditorMessages.getString("FileDocumentProvider.error.out_of_sync"), null); //$NON-NLS-1$ + throw new CoreException(status); + } + } + + /** + * Computes the initial modification stamp for the given resource. + * + * @param resource the resource + * @return the modification stamp + */ + protected long computeModificationStamp(IResource resource) { + long modificationStamp= resource.getModificationStamp(); + + IPath path= resource.getLocation(); + if (path == null) + return modificationStamp; + + modificationStamp= path.toFile().lastModified(); + return modificationStamp; + } + + /* + * @see IDocumentProvider#getModificationStamp(Object) + */ + public long getModificationStamp(Object element) { + + if (element instanceof IFileEditorInput) { + IFileEditorInput input= (IFileEditorInput) element; + return computeModificationStamp(input.getFile()); + } + + return super.getModificationStamp(element); + } + + /* + * @see IDocumentProvider#getSynchronizationStamp(Object) + */ + public long getSynchronizationStamp(Object element) { + + if (element instanceof IFileEditorInput) { + FileInfo info= (FileInfo) getElementInfo(element); + return info.fModificationStamp; + } + + return super.getSynchronizationStamp(element); + } + + /* + * @see org.eclipse.ui.texteditor.IDocumentProviderExtension#synchronize(Object) + * @since 2.0 + */ + public void synchronize(Object element) throws CoreException { + if (element instanceof IFileEditorInput) { + + IFileEditorInput input= (IFileEditorInput) element; + + FileInfo info= (FileInfo) getElementInfo(element); + if (info != null) { + + info.fFileSynchronizer.uninstall(); + input.getFile().refreshLocal(IResource.DEPTH_INFINITE, null); + info.fFileSynchronizer.install(); + + handleElementContentChanged((IFileEditorInput) element); + } + return; + + } + super.synchronize(element); + } + + /* + * @see IDocumentProvider#isDeleted(Object) + */ + public boolean isDeleted(Object element) { + + if (element instanceof IFileEditorInput) { + IFileEditorInput input= (IFileEditorInput) element; + + IPath path= input.getFile().getLocation(); + if (path == null) + return true; + + return !path.toFile().exists(); + } + + return super.isDeleted(element); + } + + /* + * @see AbstractDocumentProvider#doSaveDocument(IProgressMonitor, Object, IDocument, boolean) + */ + protected void doSaveDocument(IProgressMonitor monitor, Object element, IDocument document, boolean overwrite) throws CoreException { + if (element instanceof IFileEditorInput) { + + IFileEditorInput input= (IFileEditorInput) element; + + try { + + InputStream stream= new ByteArrayInputStream(document.get().getBytes(ResourcesPlugin.getEncoding())); + IFile file= input.getFile(); + + if (file.exists()) { + + FileInfo info= (FileInfo) getElementInfo(element); + + if (info != null && !overwrite) + checkSynchronizationState(info.fModificationStamp, file); + + // inform about the upcoming content change + fireElementStateChanging(element); + try { + file.setContents(stream, overwrite, true, monitor); + } catch (CoreException x) { + // inform about failure + fireElementStateChangeFailed(element); + throw x; + } catch (RuntimeException x) { + // inform about failure + fireElementStateChangeFailed(element); + throw x; + } + + // If here, the editor state will be flipped to "not dirty". + // Thus, the state changing flag will be reset. + + if (info != null) { + + ResourceMarkerAnnotationModel model= (ResourceMarkerAnnotationModel) info.fModel; + model.updateMarkers(info.fDocument); + + info.fModificationStamp= computeModificationStamp(file); + } + + } else { + try { + monitor.beginTask(TextEditorMessages.getString("FileDocumentProvider.task.saving"), 2000); //$NON-NLS-1$ + ContainerGenerator generator = new ContainerGenerator(file.getParent().getFullPath()); + generator.generateContainer(new SubProgressMonitor(monitor, 1000)); + file.create(stream, false, new SubProgressMonitor(monitor, 1000)); + } + finally { + monitor.done(); + } + } + + } catch (IOException x) { + IStatus s= new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, IStatus.OK, x.getMessage(), x); + throw new CoreException(s); + } + + } else { + super.doSaveDocument(monitor, element, document, overwrite); + } + } + + /* + * @see AbstractDocumentProvider#createElementInfo(Object) + */ + protected ElementInfo createElementInfo(Object element) throws CoreException { + if (element instanceof IFileEditorInput) { + + IFileEditorInput input= (IFileEditorInput) element; + + try { + input.getFile().refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor()); + } catch (CoreException x) { + handleCoreException(x,TextEditorMessages.getString("FileDocumentProvider.createElementInfo")); //$NON-NLS-1$ + } + + IDocument d= null; + IStatus s= null; + + try { + d= createDocument(element); + } catch (CoreException x) { + s= x.getStatus(); + d= new Document(); + } + + IAnnotationModel m= createAnnotationModel(element); + FileSynchronizer f= new FileSynchronizer(input); + f.install(); + + FileInfo info= new FileInfo(d, m, f); + info.fModificationStamp= computeModificationStamp(input.getFile()); + info.fStatus= s; + + return info; + } + + return super.createElementInfo(element); + } + + /* + * @see AbstractDocumentProvider#disposeElementInfo(Object, ElementInfo) + */ + protected void disposeElementInfo(Object element, ElementInfo info) { + if (info instanceof FileInfo) { + FileInfo fileInfo= (FileInfo) info; + if (fileInfo.fFileSynchronizer != null) + fileInfo.fFileSynchronizer.uninstall(); + } + + super.disposeElementInfo(element, info); + } + + /** + * Updates the element info to a change of the file content and sends out + * appropriate notifications. + * + * @param fileEditorInput the input of an text editor + */ + protected void handleElementContentChanged(IFileEditorInput fileEditorInput) { + FileInfo info= (FileInfo) getElementInfo(fileEditorInput); + + IDocument document= new Document(); + IStatus status= null; + + try { + + try { + fileEditorInput.getFile().refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor()); + } catch (CoreException x) { + handleCoreException(x, "FileDocumentProvider.handleElementContentChanged"); //$NON-NLS-1$ + } + + setDocumentContent(document, fileEditorInput, info.fEncoding); + + } catch (CoreException x) { + status= x.getStatus(); + } + + String newContent= document.get(); + + if ( !newContent.equals(info.fDocument.get())) { + + // set the new content and fire content related events + fireElementContentAboutToBeReplaced(fileEditorInput); + + removeUnchangedElementListeners(fileEditorInput, info); + + info.fDocument.removeDocumentListener(info); + info.fDocument.set(newContent); + info.fCanBeSaved= false; + info.fModificationStamp= computeModificationStamp(fileEditorInput.getFile()); + info.fStatus= status; + + addUnchangedElementListeners(fileEditorInput, info); + + fireElementContentReplaced(fileEditorInput); + + } else { + + removeUnchangedElementListeners(fileEditorInput, info); + + // fires only the dirty state related event + info.fCanBeSaved= false; + info.fModificationStamp= computeModificationStamp(fileEditorInput.getFile()); + info.fStatus= status; + + addUnchangedElementListeners(fileEditorInput, info); + + fireElementDirtyStateChanged(fileEditorInput, false); + } + } + + /** + * Sends out the notification that the file serving as document input has been moved. + * + * @param fileEditorInput the input of an text editor + * @param path the path of the new location of the file + */ + protected void handleElementMoved(IFileEditorInput fileEditorInput, IPath path) { + IWorkspace workspace= ResourcesPlugin.getWorkspace(); + IFile newFile= workspace.getRoot().getFile(path); + fireElementMoved(fileEditorInput, newFile == null ? null : new FileEditorInput(newFile)); + } + + /** + * Sends out the notification that the file serving as document input has been deleted. + * + * @param fileEditorInput the input of an text editor + */ + protected void handleElementDeleted(IFileEditorInput fileEditorInput) { + fireElementDeleted(fileEditorInput); + } + + /* + * @see AbstractDocumentProvider#getElementInfo(Object) + * It's only here to circumvent visibility issues with certain compilers. + */ + protected ElementInfo getElementInfo(Object element) { + return super.getElementInfo(element); + } + + /* + * @see AbstractDocumentProvider#doValidateState(Object, Object) + * @since 2.0 + */ + protected void doValidateState(Object element, Object computationContext) throws CoreException { + + if (element instanceof IFileEditorInput) { + IFileEditorInput input= (IFileEditorInput) element; + FileInfo info= (FileInfo) getElementInfo(input); + if (info != null) { + IFile file= input.getFile(); + if (file.isReadOnly()) { // do not use cached state here + IWorkspace workspace= file.getWorkspace(); + workspace.validateEdit(new IFile[] { file }, computationContext); + } + } + } + + super.doValidateState(element, computationContext); + } + + /* + * @see IDocumentProviderExtension#isModifiable(Object) + * @since 2.0 + */ + public boolean isModifiable(Object element) { + if (!isStateValidated(element)) { + if (element instanceof IFileEditorInput) + return true; + } + return super.isModifiable(element); + } + + /* + * @see IDocumentProvider#resetDocument(Object) + * @since 2.0 + */ + public void resetDocument(Object element) throws CoreException { + // http://dev.eclipse.org/bugs/show_bug.cgi?id=19014 + if (element instanceof IFileEditorInput) { + IFileEditorInput input= (IFileEditorInput) element; + try { + input.getFile().refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor()); + } catch (CoreException x) { + handleCoreException(x,TextEditorMessages.getString("FileDocumentProvider.resetDocument")); //$NON-NLS-1$ + } + } + super.resetDocument(element); + } +}
\ No newline at end of file diff --git a/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/IEncodingActionsConstants.java b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/IEncodingActionsConstants.java new file mode 100644 index 00000000000..9225f6561ad --- /dev/null +++ b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/IEncodingActionsConstants.java @@ -0,0 +1,68 @@ +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: + IBM Corporation - Initial implementation +**********************************************************************/ + +package org.eclipse.ui.editors.text; + +/** + * Defines the names of the encoding actions.<p> + * This interface contains constants only; it is not intended to be implemented. + * @since 2.0 + */ +public interface IEncodingActionsConstants { + + /** + * Name of the action to changes the encoding into US ASCII. + * Value is <code>"US-ASCII"</code>. + */ + static final String US_ASCII= "US-ASCII"; //$NON-NLS-1$ + + /** + * Name of the action to changes the encoding into ISO-8859-1. + * Value is <code>"ISO-8859-1"</code>. + */ + static final String ISO_8859_1= "ISO-8859-1"; //$NON-NLS-1$ + + /** + * Name of the action to changes the encoding into UTF-8. + * Value is <code>"UTF-8"</code>. + */ + static final String UTF_8= "UTF-8"; //$NON-NLS-1$ + + /** + * Name of the action to changes the encoding into UTF-16BE. + * Value is <code>"UTF-16BE"</code>. + */ + static final String UTF_16BE= "UTF-16BE"; //$NON-NLS-1$ + + /** + * Name of the action to changes the encoding into UTF-16LE. + * Value is <code>"UTF-16LE"</code>. + */ + static final String UTF_16LE= "UTF-16LE"; //$NON-NLS-1$ + + /** + * Name of the action to changes the encoding into UTF-16. + * Value is <code>"UTF-16"</code>. + */ + static final String UTF_16= "UTF-16"; //$NON-NLS-1$ + + /** + * Name of the action to changes the encoding into the system encoding. + * Value is <code>"System"</code>. + */ + static final String SYSTEM= "System"; //$NON-NLS-1$ + + /** + * Name of the action to changes the encoding into a custom encoding. + * Value is <code>"Custom"</code>. + */ + static final String CUSTOM= "Custom"; //$NON-NLS-1$ +}
\ No newline at end of file diff --git a/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/IEncodingActionsDefinitionIds.java b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/IEncodingActionsDefinitionIds.java new file mode 100644 index 00000000000..747959ae988 --- /dev/null +++ b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/IEncodingActionsDefinitionIds.java @@ -0,0 +1,68 @@ +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: + IBM Corporation - Initial implementation +**********************************************************************/ + +package org.eclipse.ui.editors.text; + + +/** + * Defines the definition ids for the encoding actions. <p> + * This interface contains constants only; it is not intended to be implemented. + * @since 2.0 + */ +public interface IEncodingActionsDefinitionIds { + /** + * Action definition id of the action to changes the encoding into US ASCII. + * Value is <code>"org.eclipse.ui.edit.text.encoding.us-ascii"</code>. + */ + public static final String US_ASCII= "org.eclipse.ui.edit.text.encoding.us-ascii"; //$NON-NLS-1$ + + /** + * Action definition id of the action to changes the encoding into ISO-8859-1. + * Value is <code>"org.eclipse.ui.edit.text.encoding.iso-8859-1"</code>. + */ + public static final String ISO_8859_1= "org.eclipse.ui.edit.text.encoding.iso-8859-1"; //$NON-NLS-1$ + + /** + * Action definition id of the action to changes the encoding into UTF-8. + * Value is <code>"org.eclipse.ui.edit.text.encoding.utf-8"</code>. + */ + public static final String UTF_8= "org.eclipse.ui.edit.text.encoding.utf-8"; //$NON-NLS-1$ + + /** + * Action definition id of the action to changes the encoding into UTF-16BE. + * Value is <code>"org.eclipse.ui.edit.text.encoding.utf-16be"</code>. + */ + public static final String UTF_16BE= "org.eclipse.ui.edit.text.encoding.utf-16be"; //$NON-NLS-1$ + + /** + * Action definition id of the action to changes the encoding into UTF-16LE. + * Value is <code>"org.eclipse.ui.edit.text.encoding.utf-16le"</code>. + */ + public static final String UTF_16LE= "org.eclipse.ui.edit.text.encoding.utf-16le"; //$NON-NLS-1$ + + /** + * Action definition id of the action to changes the encoding into UTF-16. + * Value is <code>"org.eclipse.ui.edit.text.encoding.utf-16"</code>. + */ + public static final String UTF_16= "org.eclipse.ui.edit.text.encoding.utf-16"; //$NON-NLS-1$ + + /** + * Action definition id of the action to changes the encoding into the system encoding. + * Value is <code>"org.eclipse.ui.edit.text.encoding.system"</code>. + */ + public static final String SYSTEM= "org.eclipse.ui.edit.text.encoding.system"; //$NON-NLS-1$ + + /** + * Action definition id of the action to changes the encoding into a custom encoding. + * Value is <code>"org.eclipse.ui.edit.text.encoding.custom"</code>. + */ + public static final String CUSTOM= "org.eclipse.ui.edit.text.encoding.custom"; //$NON-NLS-1$ +}
\ No newline at end of file diff --git a/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/IEncodingActionsHelpContextIds.java b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/IEncodingActionsHelpContextIds.java new file mode 100644 index 00000000000..01d83ab9015 --- /dev/null +++ b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/IEncodingActionsHelpContextIds.java @@ -0,0 +1,71 @@ +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: + IBM Corporation - Initial implementation +**********************************************************************/ + +package org.eclipse.ui.editors.text; + + +import org.eclipse.ui.texteditor.IAbstractTextEditorHelpContextIds; + +/** + * Help context ids for the encoding actions. <p> + * This interface contains constants only; it is not intended to be implemented. + * @since 2.0 + */ +public interface IEncodingActionsHelpContextIds { + + /** + * Help id of the action to changes the encoding into US ASCII. + * Default value: <code>"org.eclipse.ui.US-ASCII_action_context"</code> + */ + public static final String US_ASCII= IAbstractTextEditorHelpContextIds.PREFIX + IEncodingActionsConstants.US_ASCII + IAbstractTextEditorHelpContextIds.ACTION_POSTFIX; + + /** + * Help id of the action to changes the encoding into ISO-8859-1. + * Default value: <code>"org.eclipse.ui.ISO-8859-1_action_context"</code> + */ + public static final String ISO_8859_1= IAbstractTextEditorHelpContextIds.PREFIX + IEncodingActionsConstants.ISO_8859_1 + IAbstractTextEditorHelpContextIds.ACTION_POSTFIX; + + /** + * Help id of the action to changes the encoding into UTF-8 + * Default value: <code>"org.eclipse.ui.UTF-8_action_context"</code> + */ + public static final String UTF_8= IAbstractTextEditorHelpContextIds.PREFIX + IEncodingActionsConstants.UTF_8 + IAbstractTextEditorHelpContextIds.ACTION_POSTFIX; + + /** + * Help id of the action to changes the encoding into UTF-16BE. + * Default value: <code>"org.eclipse.ui.UTF-16BE_action_context"</code> + */ + public static final String UTF_16BE= IAbstractTextEditorHelpContextIds.PREFIX + IEncodingActionsConstants.UTF_16BE + IAbstractTextEditorHelpContextIds.ACTION_POSTFIX; + + /** + * Help id of the action to changes the encoding into UTF-16LE. + * Default value: <code>"org.eclipse.ui.UTF-16LE_action_context"</code> + */ + public static final String UTF_16LE= IAbstractTextEditorHelpContextIds.PREFIX + IEncodingActionsConstants.UTF_16LE + IAbstractTextEditorHelpContextIds.ACTION_POSTFIX; + + /** + * Help id of the action to changes the encoding into UTF-16. + * Default value: <code>"org.eclipse.ui.UTF-16_action_context"</code> + */ + public static final String UTF_16= IAbstractTextEditorHelpContextIds.PREFIX + IEncodingActionsConstants.UTF_16 + IAbstractTextEditorHelpContextIds.ACTION_POSTFIX; + + /** + * Help id of the action to changes the encoding into the system encoding. + * Default value: <code>"org.eclipse.ui.System_action_context"</code> + */ + public static final String SYSTEM= IAbstractTextEditorHelpContextIds.PREFIX + IEncodingActionsConstants.SYSTEM + IAbstractTextEditorHelpContextIds.ACTION_POSTFIX; + + /** + * Help id of the action to changes the encoding into a custom encoding. + * Default value: <code>"org.eclipse.ui.Custom_action_context"</code> + */ + public static final String CUSTOM= IAbstractTextEditorHelpContextIds.PREFIX + IEncodingActionsConstants.CUSTOM + IAbstractTextEditorHelpContextIds.ACTION_POSTFIX; +}
\ No newline at end of file diff --git a/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/IEncodingSupport.java b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/IEncodingSupport.java new file mode 100644 index 00000000000..1dbf69e229e --- /dev/null +++ b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/IEncodingSupport.java @@ -0,0 +1,40 @@ +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: + IBM Corporation - Initial implementation +**********************************************************************/ + +package org.eclipse.ui.editors.text; + +/** + * Interface to be implemented by objects supporting character encodings. + * @since 2.0 + */ +public interface IEncodingSupport{ + + /** + * Sets the character encoding. + * + * @param encoding the character encoding + */ + void setEncoding(String encoding); + + /** + * Returns the character encoding. + * + * @return the character encoding + */ + String getEncoding(); + + /** + * Returns the default character encoding. + * + * @return the default character encoding + */ + String getDefaultEncoding(); +} diff --git a/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/IStorageDocumentProvider.java b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/IStorageDocumentProvider.java new file mode 100644 index 00000000000..bc769cde043 --- /dev/null +++ b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/IStorageDocumentProvider.java @@ -0,0 +1,47 @@ +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: + IBM Corporation - Initial implementation +**********************************************************************/ + +package org.eclipse.ui.editors.text; + + +/** + * Document provider for <code>IStorage</code> based domain elements. + * Basically incorporates the concept of character encoding. + * + * @since 2.0 + */ +public interface IStorageDocumentProvider { + + /** + * Returns the default character encoding used by this provider for reading. + * + * @return the default character encoding used by this provider for reading + */ + String getDefaultEncoding(); + + /** + * Returns the character encoding for reading the given element, or + * <code>null</code> if the element is not managed by this provider. + * + * @param element the element + * @return the encoding for reading the given element + */ + String getEncoding(Object element); + + /** + * Sets the encoding for reading the given element. If <code>encoding</code> + * is <code>null</code> the workbench's character encoding should be used. + * + * @param element the element + * @param encoding the encoding to be used + */ + void setEncoding(Object element, String encoding); +} diff --git a/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/ITextEditorHelpContextIds.java b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/ITextEditorHelpContextIds.java new file mode 100644 index 00000000000..b4db6a9f77d --- /dev/null +++ b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/ITextEditorHelpContextIds.java @@ -0,0 +1,33 @@ +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: + IBM Corporation - Initial implementation +**********************************************************************/ + +package org.eclipse.ui.editors.text; + +import org.eclipse.ui.texteditor.IAbstractTextEditorHelpContextIds; + +/** + * Help context ids for the text editor. <p> + * This interface contains constants only; it is not intended to be implemented. + */ +public interface ITextEditorHelpContextIds extends IAbstractTextEditorHelpContextIds { + + /** + * Id for the text editor preference page. + * Default value: <code>"text_editor_preference_page_context"</code>. + */ + public static final String TEXT_EDITOR_PREFERENCE_PAGE= PREFIX + "text_editor_preference_page_context"; //$NON-NLS-1$ + + /** + * Id for the text editor. + * Default value: <code>"text_editor_context"</code>. + */ + public static final String TEXT_EDITOR= PREFIX + "text_editor_context"; //$NON-NLS-1$ +}
\ No newline at end of file diff --git a/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/StorageDocumentProvider.java b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/StorageDocumentProvider.java new file mode 100644 index 00000000000..c1048b74f0c --- /dev/null +++ b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/StorageDocumentProvider.java @@ -0,0 +1,352 @@ +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: + IBM Corporation - Initial implementation +**********************************************************************/ + +package org.eclipse.ui.editors.text; + + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; + +import org.eclipse.core.resources.IStorage; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.ILog; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; + +import org.eclipse.jface.text.Document; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.source.IAnnotationModel; + +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IStorageEditorInput; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.texteditor.AbstractDocumentProvider; + + + +/** + * Shareable document provider specialized for <code>IStorage</code>s. + */ +public class StorageDocumentProvider extends AbstractDocumentProvider implements IStorageDocumentProvider { + + + /** + * Bundle of all required information to allow <code>IStorage</code> as underlying document resources. + * @since 2.0 + */ + protected class StorageInfo extends ElementInfo { + + /** The flag representing the cached state whether the storage is modifiable */ + public boolean fIsModifiable= false; + /** The flag representing the cached state whether the storage is read-only */ + public boolean fIsReadOnly= true; + /** The flag representing the need to update the cached flag */ + public boolean fUpdateCache= true; + /** The encoding used to create the document from the storage or <code>null</code> for workbench encoding */ + public String fEncoding; + + /** + * Creates a new storage info. + * + * @param document the document + * @param model the annotation model + */ + public StorageInfo(IDocument document, IAnnotationModel model) { + super(document, model); + fEncoding= null; + } + }; + + /** + * Creates a new document provider. + * @since 2.0 + */ + public StorageDocumentProvider() { + super(); + } + + /** + * Intitializes the given document with the given stream. + * + * @param document the document to be initialized + * @param contentStream the stream which delivers the document content + * @exception CoreException if the given stream can not be read + * + * @deprecated use encoding based version instead + */ + protected void setDocumentContent(IDocument document, InputStream contentStream) throws CoreException { + setDocumentContent(document, contentStream, null); + } + + /** + * Intitializes the given document with the given stream using the given encoding. + * + * @param document the document to be initialized + * @param contentStream the stream which delivers the document content + * @param encoding the character encoding for reading the given stream + * @exception CoreException if the given stream can not be read + * @since 2.0 + */ + protected void setDocumentContent(IDocument document, InputStream contentStream, String encoding) throws CoreException { + + Reader in= null; + + try { + + if (encoding == null) + encoding= getDefaultEncoding(); + + in= new InputStreamReader(new BufferedInputStream(contentStream), encoding); + StringBuffer buffer= new StringBuffer(); + char[] readBuffer= new char[2048]; + int n= in.read(readBuffer); + while (n > 0) { + buffer.append(readBuffer, 0, n); + n= in.read(readBuffer); + } + + document.set(buffer.toString()); + + } catch (IOException x) { + String msg= x.getMessage() == null ? "" : x.getMessage(); //$NON-NLS-1$ + IStatus s= new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, IStatus.OK, msg, x); + throw new CoreException(s); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException x) { + } + } + } + } + + /** + * Intitializes the given document from the given editor input using the default character encoding. + * + * @param document the document to be initialized + * @param editorInput the input from which to derive the content of the document + * @return <code>true</code> if the document content could be set, <code>false</code> otherwise + * @exception CoreException if the given editor input cannot be accessed + * + * @deprecated use the encoding based version instead + * @since 2.0 + */ + protected boolean setDocumentContent(IDocument document, IEditorInput editorInput) throws CoreException { + return setDocumentContent(document, editorInput, null); + } + + /** + * Intitializes the given document from the given editor input using the given character encoding. + * + * @param document the document to be initialized + * @param editorInput the input from which to derive the content of the document + * @param encoding the character encoding used to read the editor input + * @return <code>true</code> if the document content could be set, <code>false</code> otherwise + * @exception CoreException if the given editor input cannot be accessed + * @since 2.0 + */ + protected boolean setDocumentContent(IDocument document, IEditorInput editorInput, String encoding) throws CoreException { + if (editorInput instanceof IStorageEditorInput) { + IStorage storage= ((IStorageEditorInput) editorInput).getStorage(); + setDocumentContent(document, storage.getContents(), encoding); + return true; + } + return false; + } + + /* + * @see AbstractDocumentProvider#createAnnotationModel(Object) + */ + protected IAnnotationModel createAnnotationModel(Object element) throws CoreException { + return null; + } + + /* + * @see AbstractDocumentProvider#createDocument(Object) + */ + protected IDocument createDocument(Object element) throws CoreException { + + if (element instanceof IEditorInput) { + Document document= new Document(); + if (setDocumentContent(document, (IEditorInput) element, getEncoding(element))) + return document; + } + + return null; + } + + /* + * @see AbstractDocumentProvider#createElementInfo(Object) + * @since 2.0 + */ + protected ElementInfo createElementInfo(Object element) throws CoreException { + if (element instanceof IStorageEditorInput) { + + IDocument document= null; + IStatus status= null; + + try { + document= createDocument(element); + } catch (CoreException x) { + status= x.getStatus(); + document= new Document(); + } + + ElementInfo info= new StorageInfo(document, createAnnotationModel(element)); + info.fStatus= status; + + return info; + } + + return super.createElementInfo(element); + } + + /* + * @see AbstractDocumentProvider#doSaveDocument(IProgressMonitor, Object, IDocument, boolean) + */ + protected void doSaveDocument(IProgressMonitor monitor, Object element, IDocument document, boolean overwrite) throws CoreException { + } + + /** + * Defines the standard procedure to handle <code>CoreExceptions</code>. Exceptions + * are written to the plugin log. + * + * @param exception the exception to be logged + * @param message the message to be logged + * @since 2.0 + */ + protected void handleCoreException(CoreException exception, String message) { + ILog log= Platform.getPlugin(PlatformUI.PLUGIN_ID).getLog(); + + if (message != null) + log.log(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0, message, exception)); + else + log.log(exception.getStatus()); + } + + /** + * Updates the internal cache for the given input. + * + * @param input the input whose cache will be updated + * @since 2.0 + */ + protected void updateCache(IStorageEditorInput input) throws CoreException { + StorageInfo info= (StorageInfo) getElementInfo(input); + if (info != null) { + try { + IStorage storage= input.getStorage(); + if (storage != null) { + boolean readOnly= storage.isReadOnly(); + info.fIsReadOnly= readOnly; + info.fIsModifiable= !readOnly; + } + } catch (CoreException x) { + handleCoreException(x, TextEditorMessages.getString("StorageDocumentProvider.updateCache")); //$NON-NLS-1$ + } + info.fUpdateCache= false; + } + } + + /* + * @see IDocumentProviderExtension#isReadOnly(Object) + * @since 2.0 + */ + public boolean isReadOnly(Object element) { + if (element instanceof IStorageEditorInput) { + StorageInfo info= (StorageInfo) getElementInfo(element); + if (info != null) { + if (info.fUpdateCache) { + try { + updateCache((IStorageEditorInput) element); + } catch (CoreException x) { + handleCoreException(x, TextEditorMessages.getString("StorageDocumentProvider.isReadOnly")); //$NON-NLS-1$ + } + } + return info.fIsReadOnly; + } + } + return super.isReadOnly(element); + } + + /* + * @see IDocumentProviderExtension#isModifiable(Object) + * @since 2.0 + */ + public boolean isModifiable(Object element) { + if (element instanceof IStorageEditorInput) { + StorageInfo info= (StorageInfo) getElementInfo(element); + if (info != null) { + if (info.fUpdateCache) { + try { + updateCache((IStorageEditorInput) element); + } catch (CoreException x) { + handleCoreException(x, TextEditorMessages.getString("StorageDocumentProvider.isModifiable")); //$NON-NLS-1$ + } + } + return info.fIsModifiable; + } + } + return super.isModifiable(element); + } + + /* + * @see AbstractDocumentProvider#doUpdateStateCache(Object) + * @since 2.0 + */ + protected void doUpdateStateCache(Object element) throws CoreException { + if (element instanceof IStorageEditorInput) { + StorageInfo info= (StorageInfo) getElementInfo(element); + if (info != null) + info.fUpdateCache= true; + } + super.doUpdateStateCache(element); + } + + /* + * @see IStorageDocumentProvider#getDefaultEncoding() + * @since 2.0 + */ + public String getDefaultEncoding() { + return ResourcesPlugin.getEncoding(); + } + + /* + * @see IStorageDocumentProvider#getEncoding(Object) + * @since 2.0 + */ + public String getEncoding(Object element) { + if (element instanceof IStorageEditorInput) { + StorageInfo info= (StorageInfo) getElementInfo(element); + if (info != null) + return info.fEncoding; + } + return null; + } + + /* + * @see IStorageDocumentProvider#setEncoding(Object, String) + * @since 2.0 + */ + public void setEncoding(Object element, String encoding) { + if (element instanceof IStorageEditorInput) { + StorageInfo info= (StorageInfo) getElementInfo(element); + if (info != null) + info.fEncoding= encoding; + } + } +}
\ No newline at end of file diff --git a/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/TextEditor.java b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/TextEditor.java new file mode 100644 index 00000000000..4c5efd47086 --- /dev/null +++ b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/TextEditor.java @@ -0,0 +1,322 @@ +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: + IBM Corporation - Initial implementation +**********************************************************************/ + +package org.eclipse.ui.editors.text; + + +import java.lang.reflect.InvocationTargetException; +import java.text.MessageFormat; + +import org.eclipse.swt.widgets.Shell; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IWorkspace; +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.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Plugin; + +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.IMessageProvider; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.dialogs.ProgressMonitorDialog; + +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IFileEditorInput; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.actions.WorkspaceModifyOperation; +import org.eclipse.ui.dialogs.SaveAsDialog; +import org.eclipse.ui.part.FileEditorInput; +import org.eclipse.ui.plugin.AbstractUIPlugin; + +import org.eclipse.ui.texteditor.ConvertLineDelimitersAction; +import org.eclipse.ui.texteditor.DefaultRangeIndicator; +import org.eclipse.ui.texteditor.IAbstractTextEditorHelpContextIds; +import org.eclipse.ui.texteditor.IDocumentProvider; +import org.eclipse.ui.texteditor.ITextEditorActionConstants; +import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds; +import org.eclipse.ui.texteditor.ResourceAction; +import org.eclipse.ui.texteditor.StatusTextEditor; + + + +/** + * The standard text editor for file resources (<code>IFile</code>). + * <p> + * This editor has id <code>"org.eclipse.ui.DefaultTextEditor"</code>. + * The editor's context menu has id <code>#TextEditorContext</code>. + * The editor's ruler context menu has id <code>#TextRulerContext</code>. + * </p> + * <p> + * The workbench will automatically instantiate this class when the default + * editor is needed for a workbench window. + * </p> + */ +public class TextEditor extends StatusTextEditor { + + /** + * The encoding support for the editor. + * @since 2.0 + */ + private DefaultEncodingSupport fEncodingSupport; + + /** + * Creates a new text editor. + */ + public TextEditor() { + super(); + initializeEditor(); + } + + /** + * Initializes this editor. + */ + protected void initializeEditor() { + setRangeIndicator(new DefaultRangeIndicator()); + setEditorContextMenuId("#TextEditorContext"); //$NON-NLS-1$ + setRulerContextMenuId("#TextRulerContext"); //$NON-NLS-1$ + setHelpContextId(ITextEditorHelpContextIds.TEXT_EDITOR); + + Plugin plugin= Platform.getPlugin(PlatformUI.PLUGIN_ID); + if (plugin instanceof AbstractUIPlugin) { + AbstractUIPlugin uiPlugin= (AbstractUIPlugin) plugin; + setPreferenceStore(uiPlugin.getPreferenceStore()); + } + } + + /* + * @see IWorkbenchPart#dispose() + * @since 2.0 + */ + public void dispose() { + if (fEncodingSupport != null) { + fEncodingSupport.dispose(); + fEncodingSupport= null; + } + super.dispose(); + } + + /** + * 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) { + + Shell shell= getSite().getShell(); + IEditorInput input = getEditorInput(); + + SaveAsDialog dialog= new SaveAsDialog(shell); + + IFile original= (input instanceof IFileEditorInput) ? ((IFileEditorInput) input).getFile() : null; + if (original != null) + dialog.setOriginalFile(original); + + dialog.create(); + + IDocumentProvider provider= getDocumentProvider(); + if (provider.isDeleted(input) && original != null) { + String message= MessageFormat.format(TextEditorMessages.getString("Editor.warning.save.delete"), new Object[] { original.getName() }); + dialog.setErrorMessage(null); + dialog.setMessage(message, IMessageProvider.WARNING); + } + + if (dialog.open() == Dialog.CANCEL) { + if (progressMonitor != null) + progressMonitor.setCanceled(true); + return; + } + + IPath filePath= dialog.getResult(); + if (filePath == null) { + if (progressMonitor != null) + progressMonitor.setCanceled(true); + return; + } + + IWorkspace workspace= ResourcesPlugin.getWorkspace(); + IFile file= workspace.getRoot().getFile(filePath); + final IEditorInput newInput= new FileEditorInput(file); + + WorkspaceModifyOperation op= new WorkspaceModifyOperation() { + public void execute(final IProgressMonitor monitor) throws CoreException { + getDocumentProvider().saveDocument(monitor, newInput, getDocumentProvider().getDocument(getEditorInput()), true); + } + }; + + boolean success= false; + try { + + getDocumentProvider().aboutToChange(newInput); + new ProgressMonitorDialog(shell).run(false, true, op); + success= true; + + } catch (InterruptedException x) { + } catch (InvocationTargetException x) { + + Throwable targetException= x.getTargetException(); + + String title= TextEditorMessages.getString("Editor.error.save.title"); //$NON-NLS-1$ + String msg= MessageFormat.format(TextEditorMessages.getString("Editor.error.save.message"), new Object[] { targetException.getMessage() }); //$NON-NLS-1$ + + if (targetException instanceof CoreException) { + CoreException coreException= (CoreException) targetException; + IStatus status= coreException.getStatus(); + 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 { + getDocumentProvider().changed(newInput); + if (success) + setInput(newInput); + } + + if (progressMonitor != null) + progressMonitor.setCanceled(!success); + } + + /* + * @see IEditorPart#isSaveAsAllowed() + */ + public boolean isSaveAsAllowed() { + return true; + } + + /* + * @see AbstractTextEditor#createActions() + * @since 2.0 + */ + protected void createActions() { + super.createActions(); + + ResourceAction action= new ConvertLineDelimitersAction(TextEditorMessages.getResourceBundle(), "Editor.ConvertToWindows.", this, "\r\n"); //$NON-NLS-1$ //$NON-NLS-2$ + action.setHelpContextId(IAbstractTextEditorHelpContextIds.CONVERT_LINE_DELIMITERS_TO_WINDOWS); + action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONVERT_LINE_DELIMITERS_TO_WINDOWS); + setAction(ITextEditorActionConstants.CONVERT_LINE_DELIMITERS_TO_WINDOWS, action); + + action= new ConvertLineDelimitersAction(TextEditorMessages.getResourceBundle(), "Editor.ConvertToUNIX.", this, "\n"); //$NON-NLS-1$ //$NON-NLS-2$ + action.setHelpContextId(IAbstractTextEditorHelpContextIds.CONVERT_LINE_DELIMITERS_TO_UNIX); + action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONVERT_LINE_DELIMITERS_TO_UNIX); + setAction(ITextEditorActionConstants.CONVERT_LINE_DELIMITERS_TO_UNIX, action); + + action= new ConvertLineDelimitersAction(TextEditorMessages.getResourceBundle(), "Editor.ConvertToMac.", this, "\r"); //$NON-NLS-1$ //$NON-NLS-2$ + action.setHelpContextId(IAbstractTextEditorHelpContextIds.CONVERT_LINE_DELIMITERS_TO_MAC); + action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONVERT_LINE_DELIMITERS_TO_MAC); + setAction(ITextEditorActionConstants.CONVERT_LINE_DELIMITERS_TO_MAC, action); + + // http://dev.eclipse.org/bugs/show_bug.cgi?id=17709 + markAsStateDependentAction(ITextEditorActionConstants.CONVERT_LINE_DELIMITERS_TO_WINDOWS, true); + markAsStateDependentAction(ITextEditorActionConstants.CONVERT_LINE_DELIMITERS_TO_UNIX, true); + markAsStateDependentAction(ITextEditorActionConstants.CONVERT_LINE_DELIMITERS_TO_MAC, true); + + fEncodingSupport= new DefaultEncodingSupport(); + fEncodingSupport.initialize(this); + } + + /* + * @see StatusTextEditor#getStatusHeader(IStatus) + * @since 2.0 + */ + protected String getStatusHeader(IStatus status) { + if (fEncodingSupport != null) { + String message= fEncodingSupport.getStatusHeader(status); + if (message != null) + return message; + } + return super.getStatusHeader(status); + } + + /* + * @see StatusTextEditor#getStatusBanner(IStatus) + * @since 2.0 + */ + protected String getStatusBanner(IStatus status) { + if (fEncodingSupport != null) { + String message= fEncodingSupport.getStatusBanner(status); + if (message != null) + return message; + } + return super.getStatusBanner(status); + } + + /* + * @see StatusTextEditor#getStatusMessage(IStatus) + * @since 2.0 + */ + protected String getStatusMessage(IStatus status) { + if (fEncodingSupport != null) { + String message= fEncodingSupport.getStatusMessage(status); + if (message != null) + return message; + } + return super.getStatusMessage(status); + } + + /* + * @see AbstractTextEditor#doSetInput(IEditorInput) + * @since 2.0 + */ + protected void doSetInput(IEditorInput input) throws CoreException { + super.doSetInput(input); + if (fEncodingSupport != null) + fEncodingSupport.reset(); + } + + /* + * @see IAdaptable#getAdapter(Class) + * @since 2.0 + */ + public Object getAdapter(Class adapter) { + if (IEncodingSupport.class.equals(adapter)) + return fEncodingSupport; + return super.getAdapter(adapter); + } + + /* + * @see AbstractTextEditor#editorContextMenuAboutToShow(IMenuManager) + * @since 2.0 + */ + protected void editorContextMenuAboutToShow(IMenuManager menu) { + super.editorContextMenuAboutToShow(menu); + addAction(menu, ITextEditorActionConstants.GROUP_EDIT, ITextEditorActionConstants.SHIFT_RIGHT); + addAction(menu, ITextEditorActionConstants.GROUP_EDIT, ITextEditorActionConstants.SHIFT_LEFT); + } + + /* + * @see org.eclipse.ui.texteditor.AbstractTextEditor#updatePropertyDependentActions() + * @since 2.0 + */ + protected void updatePropertyDependentActions() { + super.updatePropertyDependentActions(); + if (fEncodingSupport != null) + fEncodingSupport.reset(); + } +} diff --git a/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/TextEditorActionContributor.java b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/TextEditorActionContributor.java new file mode 100644 index 00000000000..669956d9d08 --- /dev/null +++ b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/TextEditorActionContributor.java @@ -0,0 +1,117 @@ +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: + IBM Corporation - Initial implementation +**********************************************************************/ + +package org.eclipse.ui.editors.text; + + +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; + +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchActionConstants; +import org.eclipse.ui.texteditor.BasicTextEditorActionContributor; +import org.eclipse.ui.texteditor.ITextEditor; +import org.eclipse.ui.texteditor.ITextEditorActionConstants; +import org.eclipse.ui.texteditor.RetargetTextEditorAction; + +/** + * Manages the installation and deinstallation of global actions for the default text editor. <p> + * If instantiated and used as-is, this contributor connects global actions and adds actions + * for line delimiter conversion and encpding support. <p> + * @since 2.0 + */ +public class TextEditorActionContributor extends BasicTextEditorActionContributor { + + /** Convert to Windows action. */ + private RetargetTextEditorAction fConvertToWindows; + /** Convert to UNIX action. */ + private RetargetTextEditorAction fConvertToUNIX; + /** Convert to Mac action. */ + private RetargetTextEditorAction fConvertToMac; + /** Encoding action group */ + private EncodingActionGroup fEncodingActionGroup; + + + /** + * Creates a new contributor. + */ + public TextEditorActionContributor() { + super(); + + // line delimiter conversion + fConvertToWindows= new RetargetTextEditorAction(TextEditorMessages.getResourceBundle(), "Editor.ConvertToWindows."); //$NON-NLS-1$ + fConvertToUNIX= new RetargetTextEditorAction(TextEditorMessages.getResourceBundle(), "Editor.ConvertToUNIX."); //$NON-NLS-1$ + fConvertToMac= new RetargetTextEditorAction(TextEditorMessages.getResourceBundle(), "Editor.ConvertToMac."); //$NON-NLS-1$ + + // character encoding + fEncodingActionGroup= new EncodingActionGroup(); + } + + /** + * Internally sets the active editor to the actions provided by this contributor. + * Cannot be overridden by subclasses. + * @param part the editor + */ + private void doSetActiveEditor(IEditorPart part) { + + ITextEditor textEditor= null; + if (part instanceof ITextEditor) + textEditor= (ITextEditor) part; + + // line delimiter conversion + fConvertToWindows.setAction(getAction(textEditor, ITextEditorActionConstants.CONVERT_LINE_DELIMITERS_TO_WINDOWS)); + fConvertToUNIX.setAction(getAction(textEditor, ITextEditorActionConstants.CONVERT_LINE_DELIMITERS_TO_UNIX)); + fConvertToMac.setAction(getAction(textEditor, ITextEditorActionConstants.CONVERT_LINE_DELIMITERS_TO_MAC)); + + // character encoding + fEncodingActionGroup.retarget(textEditor); + } + + /* + * @see IEditorActionBarContributor#setActiveEditor(IEditorPart) + */ + public void setActiveEditor(IEditorPart part) { + super.setActiveEditor(part); + doSetActiveEditor(part); + } + + /* + * @see IEditorActionBarContributor#init(IActionBars) + */ + public void init(IActionBars bars) { + super.init(bars); + + // line delimiter conversion + IMenuManager menuManager= bars.getMenuManager(); + IMenuManager editMenu= menuManager.findMenuUsingPath(IWorkbenchActionConstants.M_EDIT); + if (editMenu != null) { + MenuManager subMenu= new MenuManager(TextEditorMessages.getString("Editor.ConvertLineDelimiters.label")); //$NON-NLS-1$ + + subMenu.add(fConvertToWindows); + subMenu.add(fConvertToUNIX); + subMenu.add(fConvertToMac); + + editMenu.add(subMenu); + } + + // character encoding + fEncodingActionGroup.fillActionBars(bars); + } + + /* + * @see IEditorActionBarContributor#dispose() + */ + public void dispose() { + doSetActiveEditor(null); + super.dispose(); + } +} diff --git a/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/TextEditorMessages.java b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/TextEditorMessages.java new file mode 100644 index 00000000000..7b7c5eb99c6 --- /dev/null +++ b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/TextEditorMessages.java @@ -0,0 +1,30 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package org.eclipse.ui.editors.text; + +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +class TextEditorMessages { + + private static final String RESOURCE_BUNDLE= "org.eclipse.ui.editors.text.TextEditorMessages";//$NON-NLS-1$ + + private static ResourceBundle fgResourceBundle= ResourceBundle.getBundle(RESOURCE_BUNDLE); + + private TextEditorMessages() { + } + + public static String getString(String key) { + try { + return fgResourceBundle.getString(key); + } catch (MissingResourceException e) { + return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$ + } + } + + public static ResourceBundle getResourceBundle() { + return fgResourceBundle; + } +} diff --git a/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/TextEditorMessages.properties b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/TextEditorMessages.properties new file mode 100644 index 00000000000..1e997797abc --- /dev/null +++ b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/TextEditorMessages.properties @@ -0,0 +1,100 @@ +############################################################# +# +# (c) Copyright IBM Corp. 2000, 2001. +# All Rights Reserved. +# +############################################################# + +PreferencePage.description=Default Text Editor Settings +PreferencePage.fontEditor=Text Font: + +FileDocumentProvider.createElementInfo=FileDocumentProvider.createElementInfo +FileDocumentProvider.error.out_of_sync=Has been changed on the file system +FileDocumentProvider.resourceChanged=FileDocumentProvider.resourceChanged +FileDocumentProvider.task.saving=Saving +FileDocumentProvider.updateContent=FileDocumentProvider.updateContent +FileDocumentProvider.resetDocument=FileDocumentProvider.resetDocument + +StorageDocumentProvider.updateCache=StorageDocumentProvider.updateCache +StorageDocumentProvider.isReadOnly=StorageDocumentProvider.isReadOnly +StorageDocumentProvider.isModifiable=StorageDocumentProvider.isModifiable + +Editor.error.save.message=Save could not be completed. {0} +Editor.error.save.title=Problems During Save As... +Editor.warning.save.delete=The original file ''{0}'' has been deleted. + +Editor.AddMenu.label=&Add + +Editor.ConvertLineDelimiters.label=C&onvert Line Delimiters + +Editor.ConvertToWindows.label=To &Windows +Editor.ConvertToWindows.tooltip=Converts line delimiters to Windows +Editor.ConvertToWindows.image= +Editor.ConvertToWindows.description=Converts line delimiters to Windows + +Editor.ConvertToUNIX.label=To &UNIX +Editor.ConvertToUNIX.tooltip=Converts line delimiters to UNIX +Editor.ConvertToUNIX.image= +Editor.ConvertToUNIX.description=Converts line delimiters to UNIX + +Editor.ConvertToMac.label=To &Mac +Editor.ConvertToMac.tooltip=Converts line delimiters to Mac +Editor.ConvertToMac.image= +Editor.ConvertToMac.description=Converts line delimiters to Mac + + +Editor.error.unreadable_encoding.header=Character Encoding Problems +Editor.error.unreadable_encoding.banner= +Editor.error.unreadable_encoding.message_arg=This file is unreadable using the \"{0}\" character encoding. +Editor.error.unreadable_encoding.message=This file is unreadable using the current character encoding. + +Editor.error.unsupported_encoding.header=Unsupported Character Encoding +Editor.error.unsupported_encoding.banner= +Editor.error.unsupported_encoding.message_arg=Character encoding \"{0}\" is not supported by this platform. +Editor.error.unsupported_encoding.message= The current character encoding is not supported by this platform. + +Editor.ConvertEncoding.submenu.label=E&ncoding + +Editor.ConvertEncoding.default_suffix=(default) + +Editor.ConvertEncoding.System.label=Platform encoding +Editor.ConvertEncoding.System.tooltip=Use the platform character encoding +Editor.ConvertEncoding.System.image= +Editor.ConvertEncoding.System.description=Use the platform character encoding + +Editor.ConvertEncoding.US-ASCII.label=ASCII +Editor.ConvertEncoding.US-ASCII.tooltip=Use the US-ASCII character encoding +Editor.ConvertEncoding.US-ASCII.image= +Editor.ConvertEncoding.US-ASCII.description=Use the US-ASCII character encoding + +Editor.ConvertEncoding.ISO-8859-1.label=Latin 1 +Editor.ConvertEncoding.ISO-8859-1.tooltip=Use the ISO-8859-1 character encoding +Editor.ConvertEncoding.ISO-8859-1.image= +Editor.ConvertEncoding.ISO-8859-1.description=Use the ISO-8859-1 character encoding + +Editor.ConvertEncoding.UTF-8.label=UTF-8 +Editor.ConvertEncoding.UTF-8.tooltip=Use the UTF-8 character encoding +Editor.ConvertEncoding.UTF-8.image= +Editor.ConvertEncoding.UTF-8.description=Use the UTF-8 character encoding + +Editor.ConvertEncoding.UTF-16BE.label=UTF-16 (big endian) +Editor.ConvertEncoding.UTF-16BE.tooltip=Use the UTF-16BE character encoding +Editor.ConvertEncoding.UTF-16BE.image= +Editor.ConvertEncoding.UTF-16BE.description=Use the UTF-16BE character encoding + +Editor.ConvertEncoding.UTF-16LE.label=UTF-16 (little endian) +Editor.ConvertEncoding.UTF-16LE.tooltip=Use the UTF-16LE character encoding +Editor.ConvertEncoding.UTF-16LE.image= +Editor.ConvertEncoding.UTF-16LE.description=Use the UTF-16LE character encoding + +Editor.ConvertEncoding.UTF-16.label=UTF-16 +Editor.ConvertEncoding.UTF-16.tooltip=Use the UTF-16 character encoding +Editor.ConvertEncoding.UTF-16.image= +Editor.ConvertEncoding.UTF-16.description=Use the UTF-16 character encoding + +Editor.ConvertEncoding.Custom.label=&Others... +Editor.ConvertEncoding.Custom.tooltip=Use a custom character encoding +Editor.ConvertEncoding.Custom.image= +Editor.ConvertEncoding.Custom.description=Use a custom character encoding +Editor.ConvertEncoding.Custom.dialog.title=Character Encoding +Editor.ConvertEncoding.Custom.dialog.message=Enter the name of the character encoding: diff --git a/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/TextEditorPreferencePage.java b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/TextEditorPreferencePage.java new file mode 100644 index 00000000000..dbd9399c33f --- /dev/null +++ b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/TextEditorPreferencePage.java @@ -0,0 +1,118 @@ +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: + IBM Corporation - Initial implementation +**********************************************************************/ + +package org.eclipse.ui.editors.text; + + +import java.util.ResourceBundle; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; + +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Plugin; + +import org.eclipse.jface.preference.FieldEditorPreferencePage; +import org.eclipse.jface.preference.FontFieldEditor; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.preference.PreferenceConverter; +import org.eclipse.jface.resource.JFaceResources; + +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.help.WorkbenchHelp; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.eclipse.ui.texteditor.AbstractTextEditor; + +/** + * A preference page to set the font used in the default text editor. + * This preference page uses the text editor's preference bundle and + * uses the key <code>"PreferencePage.description"</code> to look up + * the page description. In addition, it uses <code>"PreferencePage.fontEditor"</code> + * for the editor description. + */ +public class TextEditorPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage { + + /** + * Indicates whether the preferences this page maniulates have been initialized. + * @since 2.0 + */ + private static boolean fgInitialized= false; + + /** + * Create the preference page. + */ + public TextEditorPreferencePage() { + super(GRID); + + setDescription(TextEditorMessages.getString("PreferencePage.description")); //$NON-NLS-1$ + Plugin plugin= Platform.getPlugin(PlatformUI.PLUGIN_ID); + if (plugin instanceof AbstractUIPlugin) { + AbstractUIPlugin uiPlugin= (AbstractUIPlugin) plugin; + setPreferenceStore(uiPlugin.getPreferenceStore()); + } + } + + /* + * @see IDialogPage#createControl(Composite) + */ + public void createControl(Composite parent) { + super.createControl(parent); + WorkbenchHelp.setHelp(getControl(), ITextEditorHelpContextIds.TEXT_EDITOR_PREFERENCE_PAGE); + } + + /* + * @see FieldEditorPreferencePage#createFieldEditors + */ + public void createFieldEditors() { + addField(new FontFieldEditor(AbstractTextEditor.PREFERENCE_FONT, TextEditorMessages.getString("PreferencePage.fontEditor"), getFieldEditorParent())); //$NON-NLS-1$ + } + + /* + * @see IWorkbenchPreferencePage#init + */ + public void init(IWorkbench workbench) { + } + + /** + * Initialzes the defaults for the given store. + * @param store the preference store + * @since 2.0 + */ + public static void initDefaults(IPreferenceStore store) { + + if (fgInitialized) + return; + + fgInitialized= true; + + Font font= JFaceResources.getTextFont(); + if (font != null) { + FontData[] data= font.getFontData(); + if (data != null && data.length > 0) + PreferenceConverter.setDefault(store, AbstractTextEditor.PREFERENCE_FONT, data[0]); + } + + Display display= Display.getDefault(); + Color color= display.getSystemColor(SWT.COLOR_LIST_FOREGROUND); + PreferenceConverter.setDefault(store, AbstractTextEditor.PREFERENCE_COLOR_FOREGROUND, color.getRGB()); + store.setDefault(AbstractTextEditor.PREFERENCE_COLOR_FOREGROUND_SYSTEM_DEFAULT, true); + + color= display.getSystemColor(SWT.COLOR_LIST_BACKGROUND); + PreferenceConverter.setDefault(store, AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND, color.getRGB()); + store.setDefault(AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT, true); + } +} diff --git a/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/package.html b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/package.html new file mode 100644 index 00000000000..7e26e13bc9e --- /dev/null +++ b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/package.html @@ -0,0 +1,13 @@ +<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> + <meta name="Author" content="IBM"> + <meta name="GENERATOR" content="Mozilla/4.51 [en] (WinNT; I) [Netscape]"> + <title>Package-level Javadoc</title> +</head> +<body> +Provides a standard text editor and a file-based document +provider. +</body> +</html> diff --git a/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/AddTaskAction.java b/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/AddTaskAction.java new file mode 100644 index 00000000000..0769f45367d --- /dev/null +++ b/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/AddTaskAction.java @@ -0,0 +1,60 @@ +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: + IBM Corporation - Initial implementation +**********************************************************************/ + +package org.eclipse.ui.texteditor; + + +import java.util.Map; +import java.util.ResourceBundle; + +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; + +import org.eclipse.ui.views.tasklist.TaskPropertiesDialog; + + +/** + * Creates a new task marker. Uses the Workbench's task properties dialog. + * @since 2.0 + */ +public class AddTaskAction extends AddMarkerAction { + + /** + * Creates a new action for the given text editor. The action configures its + * visual representation from the given resource bundle. + * + * @param bundle the resource bundle + * @param prefix a prefix to be prepended to the various resource keys + * (described in <code>ResourceAction</code> constructor), or + * <code>null</code> if none + * @param editor the text editor + * @see ResourceAction#ResourceAction + */ + public AddTaskAction(ResourceBundle bundle, String prefix, ITextEditor editor) { + super(bundle, prefix, editor, IMarker.TASK, false); + } + + /* + * @see IAction#run() + */ + public void run() { + + IResource resource= getResource(); + if (resource == null) + return; + Map attributes= getInitialAttributes(); + + TaskPropertiesDialog dialog = new TaskPropertiesDialog(getTextEditor().getSite().getShell()); + dialog.setResource(resource); + dialog.setInitialAttributes(attributes); + dialog.open(); + } +} diff --git a/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/SelectMarkerRulerAction.java b/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/SelectMarkerRulerAction.java new file mode 100644 index 00000000000..a1b599e7ba4 --- /dev/null +++ b/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/SelectMarkerRulerAction.java @@ -0,0 +1,278 @@ +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: + IBM Corporation - Initial implementation +**********************************************************************/ + + +package org.eclipse.ui.texteditor; + + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.ResourceBundle; + +import org.eclipse.swt.widgets.Shell; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.ILog; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; + +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.source.Annotation; +import org.eclipse.jface.text.source.IAnnotationModel; +import org.eclipse.jface.text.source.IVerticalRuler; +import org.eclipse.jface.text.source.IVerticalRulerInfo; +import org.eclipse.jface.viewers.StructuredSelection; + +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.views.tasklist.TaskList; + + +/** + * A ruler action which can select the textual range of a marker + * that has a visual representation in the vertical ruler. + * <p> + * This class may be instantiated but is not intended for subclassing. + * </p> + * @since 2.0 + */ +public class SelectMarkerRulerAction extends ResourceAction implements IUpdate { + + /** The vertical ruler info of the action's editor */ + private IVerticalRulerInfo fRuler; + /** The associated editor */ + private ITextEditor fTextEditor; + /** The cached list of markers including a given vertical ruler location */ + private List fMarkers; + /** The action's resource bundle */ + private ResourceBundle fBundle; + /** The prefix for resource bundle lookups */ + private String fPrefix; + + /** + * Creates a new action for the given ruler and editor. The action configures + * its visual representation from the given resource bundle. + * + * @param bundle the resource bundle + * @param prefix a prefix to be prepended to the various resource keys + * (described in <code>ResourceAction</code> constructor), or <code>null</code> if none + * @param editor the editor + * @param ruler the ruler + * + * @see ResourceAction#ResourceAction + */ + public SelectMarkerRulerAction(ResourceBundle bundle, String prefix, ITextEditor editor, IVerticalRulerInfo ruler) { + super(bundle, prefix); + fRuler= ruler; + fTextEditor= editor; + + fBundle= bundle; + fPrefix= prefix; + } + + /** + * @deprecated use <code>SelectMarkerRulerInfoAction(ResourceBundle, String, IVerticalRulerInfo, ITextEditor)</code> + */ + public SelectMarkerRulerAction(ResourceBundle bundle, String prefix, IVerticalRuler ruler, ITextEditor editor) { + this(bundle, prefix, editor, ruler); + } + + /* + * @see IUpdate#update() + */ + public void update() { + fMarkers= getMarkers(); + setEnabled(!fMarkers.isEmpty()); + } + + /* + * @see Action#run() + */ + public void run() { + + IMarker marker= chooseMarker(fMarkers); + if (MarkerUtilities.isMarkerType(marker, IMarker.TASK) || MarkerUtilities.isMarkerType(marker, IMarker.PROBLEM)) { + IWorkbenchPage page= fTextEditor.getSite().getPage(); + IViewPart view= view= page.findView("org.eclipse.ui.views.TaskList"); //$NON-NLS-1$ + if (view instanceof TaskList) { + StructuredSelection ss= new StructuredSelection(marker); + ((TaskList) view).setSelection(ss, true); + } else { + int offset= MarkerUtilities.getCharStart(marker); + int endOffset= MarkerUtilities.getCharEnd(marker); + if (offset > -1 && endOffset > -1) + fTextEditor.selectAndReveal(offset, endOffset - offset); + } + } + } + + /** + * Chooses the marker with the highest layer. If there are multiple + * markers at the found layer, the first marker is taken. + * + * @param markers the list of markers to choose from + * @return the chosen marker + */ + protected IMarker chooseMarker(List markers) { + + AbstractMarkerAnnotationModel model= getAnnotationModel(); + + IMarker marker= null; + int maxLayer= 0; + + Iterator iter= markers.iterator(); + while (iter.hasNext()) { + IMarker m= (IMarker) iter.next(); + Annotation a= model.getMarkerAnnotation(m); + // http://dev.eclipse.org/bugs/show_bug.cgi?id=18960 + if (a != null) { + int l= a.getLayer(); + if (l == maxLayer) { + if (marker == null) + marker= m; + } else if (l > maxLayer) { + maxLayer= l; + marker= m; + } + } + } + + return marker; + } + + /** + * Returns the resource for which to create the marker, + * or <code>null</code> if there is no applicable resource. + * + * @return the resource for which to create the marker or <code>null</code> + */ + protected IResource getResource() { + IEditorInput input= fTextEditor.getEditorInput(); + + IResource resource= (IResource) input.getAdapter(IFile.class); + + if (resource == null) + resource= (IResource) input.getAdapter(IResource.class); + + return resource; + } + + /** + * Returns the <code>AbstractMarkerAnnotationModel</code> of the editor's input. + * + * @return the marker annotation model + */ + protected AbstractMarkerAnnotationModel getAnnotationModel() { + IDocumentProvider provider= fTextEditor.getDocumentProvider(); + IAnnotationModel model= provider.getAnnotationModel(fTextEditor.getEditorInput()); + if (model instanceof AbstractMarkerAnnotationModel) + return (AbstractMarkerAnnotationModel) model; + return null; + } + + /** + * Returns the <code>IDocument</code> of the editor's input. + * + * @return the document of the editor's input + */ + protected IDocument getDocument() { + IDocumentProvider provider= fTextEditor.getDocumentProvider(); + return provider.getDocument(fTextEditor.getEditorInput()); + } + + /** + * Checks whether a position includes the ruler's line of activity. + * + * @param position the position to be checked + * @param document the document the position refers to + * @return <code>true</code> if the line is included by the given position + */ + protected boolean includesRulerLine(Position position, IDocument document) { + + if (position != null) { + try { + int markerLine= document.getLineOfOffset(position.getOffset()); + int line= fRuler.getLineOfLastMouseButtonActivity(); + if (line == markerLine) + return true; + // commented because of "1GEUOZ9: ITPJUI:ALL - Confusing UI for multiline Bookmarks and Tasks" + // return (markerLine <= line && line <= document.getLineOfOffset(position.getOffset() + position.getLength())); + } catch (BadLocationException x) { + } + } + + return false; + } + + /** + * Handles core exceptions. This implementation logs the exceptions + * with the workbech plugin and shows an error dialog. + * + * @param exception the exception to be handled + * @param message the message to be logged with the given exception + */ + protected void handleCoreException(CoreException exception, String message) { + ILog log= Platform.getPlugin(PlatformUI.PLUGIN_ID).getLog(); + + if (message != null) + log.log(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0, message, null)); + + log.log(exception.getStatus()); + + + Shell shell= fTextEditor.getSite().getShell(); + String title= getString(fBundle, fPrefix + "error.dialog.title", fPrefix + "error.dialog.title"); //$NON-NLS-2$ //$NON-NLS-1$ + String msg= getString(fBundle, fPrefix + "error.dialog.message", fPrefix + "error.dialog.message"); //$NON-NLS-2$ //$NON-NLS-1$ + + ErrorDialog.openError(shell, title, msg, exception.getStatus()); + } + + /** + * Returns all markers which include the ruler's line of activity. + * + * @return all markers which include the ruler's line of activity + */ + protected List getMarkers() { + + List markers= new ArrayList(); + + IResource resource= getResource(); + IDocument document= getDocument(); + AbstractMarkerAnnotationModel model= getAnnotationModel(); + + if (resource != null && model != null && resource.exists()) { + try { + IMarker[] allMarkers= resource.findMarkers(null, true, IResource.DEPTH_ZERO); + if (allMarkers != null) { + for (int i= 0; i < allMarkers.length; i++) { + if (includesRulerLine(model.getMarkerPosition(allMarkers[i]), document)) { + markers.add(allMarkers[i]); + } + } + } + } catch (CoreException x) { + handleCoreException(x, TextEditorMessages.getString("SelectMarkerRulerAction.getMarker")); //$NON-NLS-1$ + } + } + + return markers; + } +} diff --git a/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/SelectMarkerRulerInfoAction.java b/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/SelectMarkerRulerInfoAction.java new file mode 100644 index 00000000000..26eb9a86e44 --- /dev/null +++ b/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/SelectMarkerRulerInfoAction.java @@ -0,0 +1,32 @@ +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: + IBM Corporation - Initial implementation +**********************************************************************/ + + +package org.eclipse.ui.texteditor; + + +import java.util.ResourceBundle; +import org.eclipse.jface.text.source.IVerticalRulerInfo; + + +/** + * @deprecated use <code>SelectMarkerRulerAction</code> instead + * @since 2.0 + */ +public class SelectMarkerRulerInfoAction extends SelectMarkerRulerAction { + + /** + * @deprecated use super class instead + */ + public SelectMarkerRulerInfoAction(ResourceBundle bundle, String prefix, IVerticalRulerInfo ruler, ITextEditor editor) { + super(bundle, prefix, editor, ruler); + } +} diff --git a/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/SelectRulerAction.java b/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/SelectRulerAction.java new file mode 100644 index 00000000000..56683a44515 --- /dev/null +++ b/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/SelectRulerAction.java @@ -0,0 +1,30 @@ +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: + IBM Corporation - Initial implementation +**********************************************************************/ + +package org.eclipse.ui.texteditor; + + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.text.source.IVerticalRulerInfo; + +/** + * Adapter for the select marker action. + * @since 2.0 + */ +public class SelectRulerAction extends AbstractRulerActionDelegate { + + /* + * @see AbstractRulerActionDelegate#createAction(ITextEditor, IVerticalRulerInfo) + */ + protected IAction createAction(ITextEditor editor, IVerticalRulerInfo rulerInfo) { + return new SelectMarkerRulerAction(TextEditorMessages.getResourceBundle(), "Editor.SelectMarker.", editor, rulerInfo); //$NON-NLS-1$ + } +} diff --git a/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/TaskRulerAction.java b/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/TaskRulerAction.java new file mode 100644 index 00000000000..818c39819eb --- /dev/null +++ b/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/TaskRulerAction.java @@ -0,0 +1,76 @@ +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v0.5 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v05.html + +Contributors: + IBM Corporation - Initial implementation +**********************************************************************/ + + +package org.eclipse.ui.texteditor; + + +import java.util.ResourceBundle; + +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.text.source.IVerticalRulerInfo; + +import org.eclipse.ui.views.tasklist.TaskPropertiesDialog; + + + +/** + * Adapter for the marker ruler action creating/removing tasks. + * @since 2.0 + */ +public class TaskRulerAction extends AbstractRulerActionDelegate { + + /** + * Adds a task marker over the ruler context menu. Uses the Workbench's Task properties dialog. + */ + static class TaskMarkerRulerAction extends MarkerRulerAction { + + /** + * Creates a new action for the given ruler and editor. The action configures + * its visual representation from the given resource bundle. + * + * @param bundle the resource bundle + * @param prefix a prefix to be prepended to the various resource keys + * (described in <code>ResourceAction</code> constructor), or + * <code>null</code> if none + * @param editor the editor + * @param ruler the ruler + * @see ResourceAction#ResourceAction + */ + public TaskMarkerRulerAction(ResourceBundle bundle, String prefix, ITextEditor editor, IVerticalRulerInfo ruler) { + super(bundle, prefix, editor, ruler, IMarker.TASK, false); + } + + /* + * @see MarkerRulerAction#addMarker() + */ + protected void addMarker() { + IResource resource= getResource(); + if (resource == null) + return; + + TaskPropertiesDialog dialog = new TaskPropertiesDialog(getTextEditor().getSite().getShell()); + dialog.setResource(resource); + dialog.setInitialAttributes(getInitialAttributes()); + dialog.open(); + } + }; + + /* + * @see AbstractRulerActionDelegate#createAction(ITextEditor, IVerticalRulerInfo) + */ + protected IAction createAction(ITextEditor editor, IVerticalRulerInfo rulerInfo) { + return new TaskMarkerRulerAction(TextEditorMessages.getResourceBundle(), "Editor.ManageTasks.", editor, rulerInfo); //$NON-NLS-1$ + } +} diff --git a/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/TextEditorMessages.java b/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/TextEditorMessages.java new file mode 100644 index 00000000000..4b521b117f9 --- /dev/null +++ b/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/TextEditorMessages.java @@ -0,0 +1,30 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package org.eclipse.ui.texteditor; + +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +class TextEditorMessages { + + private static final String RESOURCE_BUNDLE= "org.eclipse.ui.texteditor.TextEditorMessages"; //$NON-NLS-1$ + + private static ResourceBundle fgResourceBundle= ResourceBundle.getBundle(RESOURCE_BUNDLE); + + private TextEditorMessages() { + } + + public static String getString(String key) { + try { + return fgResourceBundle.getString(key); + } catch (MissingResourceException e) { + return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$ + } + } + + public static ResourceBundle getResourceBundle() { + return fgResourceBundle; + } +} diff --git a/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/TextEditorMessages.properties b/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/TextEditorMessages.properties new file mode 100644 index 00000000000..cd3fe638f97 --- /dev/null +++ b/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/TextEditorMessages.properties @@ -0,0 +1,39 @@ +############################################################# +# +# (c) Copyright IBM Corp. 2000, 2001. +# All Rights Reserved. +# +############################################################# + +Editor.AddTask.label=&Task... +Editor.AddTask.tooltip=Add Task +Editor.AddTask.image= +Editor.AddTask.description=Add Task +Editor.AddTask.dialog.title=Add Task +Editor.AddTask.dialog.message=Enter Task description +Editor.AddTask.error.dialog.title=Add Task +Editor.AddTask.error.dialog.message=Problems adding new task + +Editor.ManageTasks.tooltip=Adds and Removes Tasks +Editor.ManageTasks.image= +Editor.ManageTasks.description=Adds and removes Tasks +Editor.ManageTasks.add.label=Add &Task... +Editor.ManageTasks.remove.label=Remove &Task +Editor.ManageTasks.add.dialog.title=Add Task +Editor.ManageTasks.add.dialog.message=Enter Task description +Editor.ManageTasks.error.dialog.title=Managing Tasks +Editor.ManageTasks.error.dialog.message=Problems managing tasks + +Editor.SelectMarker.tooltip=Selects the marker's range +Editor.SelectMarker.image= +Editor.SelectMarker.description=Selects the Marker's Range +Editor.SelectMarker.label=Select &Marker Range +Editor.SelectMarker.error.dialog.title=Selecting Marker Range +Editor.SelectMarker.error.dialog.message=Problems selecting marker range + +MarkerRulerAction.addMarker=MarkerRulerAction.addMarker +MarkerRulerAction.getMarker=MarkerRulerAction.getMarker +MarkerRulerAction.removeMarkers=MarkerRulerAction.removeMarkers + +SelectMarkerRulerAction.getMarker=SelectMarkerRulerAction.getMarker +SelectMarkerRulerInfoAction.getMarker=SelectMarkerRulerInfoAction.getMarker |