X-Git-Url: http://secure.phpeclipse.com diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPUnitEditor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPUnitEditor.java index 63c79a4..833c8f8 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPUnitEditor.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPUnitEditor.java @@ -1,16 +1,23 @@ package net.sourceforge.phpeclipse.phpeditor; +import java.lang.reflect.InvocationTargetException; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import net.sourceforge.phpdt.core.ICompilationUnit; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.ISourceRange; +import net.sourceforge.phpdt.core.ISourceReference; +import net.sourceforge.phpdt.core.JavaModelException; import net.sourceforge.phpdt.internal.compiler.parser.Scanner; import net.sourceforge.phpdt.internal.ui.text.ContentAssistPreference; import net.sourceforge.phpdt.internal.ui.text.PHPPairMatcher; import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionManager; import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionUI; import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionUI.ExitFlags; +import net.sourceforge.phpdt.ui.IWorkingCopyManager; import net.sourceforge.phpdt.ui.PreferenceConstants; import net.sourceforge.phpdt.ui.text.JavaTextTools; import net.sourceforge.phpeclipse.PHPCore; @@ -18,11 +25,18 @@ import net.sourceforge.phpeclipse.PHPeclipsePlugin; import net.sourceforge.phpeclipse.phpeditor.php.IPHPPartitionScannerConstants; 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.Preferences; import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.dialogs.IMessageProvider; import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.PreferenceConverter; import org.eclipse.jface.text.BadLocationException; @@ -39,9 +53,9 @@ import org.eclipse.jface.text.contentassist.IContentAssistant; import org.eclipse.jface.text.source.IOverviewRuler; import org.eclipse.jface.text.source.ISourceViewer; import org.eclipse.jface.text.source.IVerticalRuler; -import org.eclipse.jface.text.source.SourceViewer; import org.eclipse.jface.text.source.SourceViewerConfiguration; import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.swt.custom.VerifyKeyListener; import org.eclipse.swt.events.VerifyEvent; import org.eclipse.swt.graphics.Color; @@ -53,8 +67,11 @@ import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IFileEditorInput; import org.eclipse.ui.actions.ActionContext; +import org.eclipse.ui.actions.WorkspaceModifyOperation; +import org.eclipse.ui.dialogs.SaveAsDialog; import org.eclipse.ui.editors.text.IStorageDocumentProvider; import org.eclipse.ui.help.WorkbenchHelp; +import org.eclipse.ui.part.FileEditorInput; import org.eclipse.ui.texteditor.IDocumentProvider; /********************************************************************** @@ -334,7 +351,7 @@ public class PHPUnitEditor extends PHPEditor { // // }; - class AdaptedSourceViewer extends SourceViewer { + class AdaptedSourceViewer extends JavaSourceViewer { private List fTextConverters; private boolean fIgnoreTextConverters = false; @@ -577,12 +594,12 @@ public class PHPUnitEditor extends PHPEditor { } - // private static class BracketLevel { - // int fOffset; - // int fLength; - // LinkedPositionManager fManager; - // LinkedPositionUI fEditor; - // }; + private static class BracketLevel { + int fOffset; + int fLength; + LinkedPositionManager fManager; + LinkedPositionUI fEditor; + }; private class BracketInserter implements VerifyKeyListener, LinkedPositionUI.ExitListener { @@ -807,6 +824,12 @@ public class PHPUnitEditor extends PHPEditor { } } + + /** The editor's save policy */ + protected ISavePolicy fSavePolicy; + /** Listener to annotation model changes that updates the error tick in the tab image */ + private JavaEditorErrorTickUpdater fJavaEditorErrorTickUpdater; + /** The editor's paint manager */ // private PaintManager fPaintManager; /** The editor's bracket painter */ @@ -826,6 +849,8 @@ public class PHPUnitEditor extends PHPEditor { /** The preference property change listener for php core. */ // private IPropertyChangeListener fPropertyChangeListener = new PropertyChangeListener(); + /** The remembered java element */ + private IJavaElement fRememberedElement; /** The remembered selection */ private ITextSelection fRememberedSelection; /** The remembered php element offset */ @@ -988,7 +1013,63 @@ public class PHPUnitEditor extends PHPEditor { setDocumentProvider(PHPeclipsePlugin.getDefault().getCompilationUnitDocumentProvider()); setEditorContextMenuId("#PHPEditorContext"); //$NON-NLS-1$ setRulerContextMenuId("#PHPRulerContext"); //$NON-NLS-1$ + setOutlinerContextMenuId("#PHPOutlinerContext"); //$NON-NLS-1$ + // don't set help contextId, we install our own help context + fSavePolicy = null; + fJavaEditorErrorTickUpdater = new JavaEditorErrorTickUpdater(this); + } + + /* + * @see JavaEditor#getElementAt(int) + */ + protected IJavaElement getElementAt(int offset) { + return getElementAt(offset, true); + } + + /** + * Returns the most narrow element including the given offset. If reconcile + * is true the editor's input element is reconciled in advance. If it is + * false this method only returns a result if the editor's input element + * does not need to be reconciled. + * + * @param offset the offset included by the retrieved element + * @param reconcile true if working copy should be reconciled + */ + protected IJavaElement getElementAt(int offset, boolean reconcile) { + IWorkingCopyManager manager = PHPeclipsePlugin.getDefault().getWorkingCopyManager(); + ICompilationUnit unit = manager.getWorkingCopy(getEditorInput()); + + if (unit != null) { + try { + if (reconcile) { + synchronized (unit) { + unit.reconcile(); + } + return unit.getElementAt(offset); + } else if (unit.isConsistent()) + return unit.getElementAt(offset); + + } catch (JavaModelException x) { + PHPeclipsePlugin.log(x.getStatus()); + // nothing found, be tolerant and go on + } + } + + return null; + } + + /* + * @see JavaEditor#getCorrespondingElement(IJavaElement) + */ + protected IJavaElement getCorrespondingElement(IJavaElement element) { + try { + return EditorUtility.getWorkingCopy(element, true); + } catch (JavaModelException x) { + PHPeclipsePlugin.log(x.getStatus()); + // nothing found, be tolerant and go on + } + return null; } public void createPartControl(Composite parent) { @@ -1039,8 +1120,8 @@ public class PHPUnitEditor extends PHPEditor { ISourceViewer sourceViewer = getSourceViewer(); if (sourceViewer instanceof ITextViewerExtension) - ((ITextViewerExtension) sourceViewer).prependVerifyKeyListener(fBracketInserter); - + ((ITextViewerExtension) sourceViewer).prependVerifyKeyListener(fBracketInserter); + } private static char getPeerCharacter(char character) { @@ -1064,7 +1145,86 @@ public class PHPUnitEditor extends PHPEditor { throw new IllegalArgumentException(); } } + /** + * The compilation unit editor implementation of this AbstractTextEditor + * method asks the user for the workspace path of a file resource and saves the document + * there. See http://dev.eclipse.org/bugs/show_bug.cgi?id=6295 + */ + 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 == null) { + // editor has been programmatically closed while the dialog was open + return; + } + + if (provider.isDeleted(input) && original != null) { + String message = PHPEditorMessages.getFormattedString("CompilationUnitEditor.warning.save.delete", new Object[] { original.getName()}); //$NON-NLS-1$ + 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 { + + provider.aboutToChange(newInput); + new ProgressMonitorDialog(shell).run(false, true, op); + success = true; + + } catch (InterruptedException x) { + } catch (InvocationTargetException x) { + + Throwable t = x.getTargetException(); + if (t instanceof CoreException) { + CoreException cx = (CoreException) t; + ErrorDialog.openError(shell, PHPEditorMessages.getString("CompilationUnitEditor.error.saving.title2"), PHPEditorMessages.getString("CompilationUnitEditor.error.saving.message2"), cx.getStatus()); //$NON-NLS-1$ //$NON-NLS-2$ + } else { + MessageDialog.openError(shell, PHPEditorMessages.getString("CompilationUnitEditor.error.saving.title3"), PHPEditorMessages.getString("CompilationUnitEditor.error.saving.message3") + t.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$ + } + + } finally { + provider.changed(newInput); + if (success) + setInput(newInput); + } + + if (progressMonitor != null) + progressMonitor.setCanceled(!success); + } /* * @see AbstractTextEditor#doSetInput(IEditorInput) */ @@ -1303,11 +1463,11 @@ public class PHPUnitEditor extends PHPEditor { // fPropertyChangeListener = null; // } - // if (fJavaEditorErrorTickUpdater != null) { - // fJavaEditorErrorTickUpdater.dispose(); - // fJavaEditorErrorTickUpdater= null; - // } - // + if (fJavaEditorErrorTickUpdater != null) { + fJavaEditorErrorTickUpdater.dispose(); + fJavaEditorErrorTickUpdater = null; + } + // if (fSelectionHistory != null) // fSelectionHistory.dispose(); @@ -1429,13 +1589,13 @@ public class PHPUnitEditor extends PHPEditor { return; } - if (OVERVIEW_RULER.equals(p)) { - if (isOverviewRulerVisible()) - showOverviewRuler(); - else - hideOverviewRuler(); - return; - } + // if (OVERVIEW_RULER.equals(p)) { + // if (isOverviewRulerVisible()) + // showOverviewRuler(); + // else + // hideOverviewRuler(); + // return; + // } // AnnotationType type = getAnnotationType(p); // if (type != null) { @@ -1579,6 +1739,35 @@ public class PHPUnitEditor extends PHPEditor { } /* + * @see JavaEditor#setOutlinePageInput(JavaOutlinePage, IEditorInput) + */ + protected void setOutlinePageInput(JavaOutlinePage page, IEditorInput input) { + if (page != null) { + IWorkingCopyManager manager = PHPeclipsePlugin.getDefault().getWorkingCopyManager(); + page.setInput(manager.getWorkingCopy(input)); + } + } + + /* + * @see AbstractTextEditor#performSaveOperation(WorkspaceModifyOperation, IProgressMonitor) + */ + protected void performSaveOperation(WorkspaceModifyOperation operation, IProgressMonitor progressMonitor) { + IDocumentProvider p = getDocumentProvider(); + if (p instanceof PHPDocumentProvider) { + PHPDocumentProvider cp = (PHPDocumentProvider) p; + cp.setSavePolicy(fSavePolicy); + } + + try { + super.performSaveOperation(operation, progressMonitor); + } finally { + if (p instanceof PHPDocumentProvider) { + PHPDocumentProvider cp = (PHPDocumentProvider) p; + cp.setSavePolicy(null); + } + } + } + /* * @see AbstractTextEditor#doSaveAs */ public void doSaveAs() { @@ -1664,4 +1853,109 @@ public class PHPUnitEditor extends PHPEditor { } return true; } + /* + * @see IReconcilingParticipant#reconciled() + */ + public void reconciled() { + if (synchronizeOutlineOnCursorMove()) { + Shell shell = getSite().getShell(); + if (shell != null && !shell.isDisposed()) { + shell.getDisplay().asyncExec(new Runnable() { + public void run() { + synchronizeOutlinePageSelection(); + } + }); + } + } + } + + private boolean synchronizeOutlineOnCursorMove() { + return PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE); + } + protected void updateStateDependentActions() { + super.updateStateDependentActions(); + fGenerateActionGroup.editorStateChanged(); + } + + /** + * Returns the updated java element for the old java element. + */ + private IJavaElement findElement(IJavaElement element) { + + if (element == null) + return null; + + IWorkingCopyManager manager = PHPeclipsePlugin.getDefault().getWorkingCopyManager(); + ICompilationUnit unit = manager.getWorkingCopy(getEditorInput()); + + if (unit != null) { + try { + + synchronized (unit) { + unit.reconcile(); + } + IJavaElement[] findings = unit.findElements(element); + if (findings != null && findings.length > 0) + return findings[0]; + + } catch (JavaModelException x) { + PHPeclipsePlugin.log(x.getStatus()); + // nothing found, be tolerant and go on + } + } + + return null; + } + + /** + * Returns the offset of the given Java element. + */ + private int getOffset(IJavaElement element) { + if (element instanceof ISourceReference) { + ISourceReference sr = (ISourceReference) element; + try { + ISourceRange srcRange = sr.getSourceRange(); + if (srcRange != null) + return srcRange.getOffset(); + } catch (JavaModelException e) { + } + } + return -1; + } + + /* + * @see AbstractTextEditor#rememberSelection() + */ + protected void rememberSelection() { + ISelectionProvider sp = getSelectionProvider(); + fRememberedSelection = (sp == null ? null : (ITextSelection) sp.getSelection()); + if (fRememberedSelection != null) { + fRememberedElement = getElementAt(fRememberedSelection.getOffset(), true); + fRememberedElementOffset = getOffset(fRememberedElement); + } + } + + /* + * @see AbstractTextEditor#restoreSelection() + */ + protected void restoreSelection() { + + try { + + if (getSourceViewer() == null || fRememberedSelection == null) + return; + + IJavaElement newElement = findElement(fRememberedElement); + int newOffset = getOffset(newElement); + int delta = (newOffset > -1 && fRememberedElementOffset > -1) ? newOffset - fRememberedElementOffset : 0; + if (isValidSelection(delta + fRememberedSelection.getOffset(), fRememberedSelection.getLength())) + selectAndReveal(delta + fRememberedSelection.getOffset(), fRememberedSelection.getLength()); + + } finally { + fRememberedSelection = null; + fRememberedElement = null; + fRememberedElementOffset = -1; + } + } + }