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;
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;
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;
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;
/**********************************************************************
//
// };
- class AdaptedSourceViewer extends SourceViewer {
+ class AdaptedSourceViewer extends JavaSourceViewer {
private List fTextConverters;
private boolean fIgnoreTextConverters = false;
}
- // 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 {
}
}
+
+ /** 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 */
/** 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 */
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 <code>reconcile</code>
+ * is <code>true</code> the editor's input element is reconciled in advance. If it is
+ * <code>false</code> 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 <code>true</code> 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) {
ISourceViewer sourceViewer = getSourceViewer();
if (sourceViewer instanceof ITextViewerExtension)
- ((ITextViewerExtension) sourceViewer).prependVerifyKeyListener(fBracketInserter);
-
+ ((ITextViewerExtension) sourceViewer).prependVerifyKeyListener(fBracketInserter);
+
}
private static char getPeerCharacter(char character) {
throw new IllegalArgumentException();
}
}
+ /**
+ * The compilation unit editor implementation of this <code>AbstractTextEditor</code>
+ * 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)
*/
// fPropertyChangeListener = null;
// }
- // if (fJavaEditorErrorTickUpdater != null) {
- // fJavaEditorErrorTickUpdater.dispose();
- // fJavaEditorErrorTickUpdater= null;
- // }
- //
+ if (fJavaEditorErrorTickUpdater != null) {
+ fJavaEditorErrorTickUpdater.dispose();
+ fJavaEditorErrorTickUpdater = null;
+ }
+
// if (fSelectionHistory != null)
// fSelectionHistory.dispose();
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) {
}
/*
+ * @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() {
}
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;
+ }
+ }
+
}