1 package net.sourceforge.phpeclipse.phpeditor;
3 import java.text.MessageFormat;
4 import java.util.ArrayList;
5 import java.util.Iterator;
8 import net.sourceforge.phpdt.core.ICompilationUnit;
9 import net.sourceforge.phpdt.core.IJavaElement;
10 import net.sourceforge.phpdt.core.IMember;
11 import net.sourceforge.phpdt.core.ISourceRange;
12 import net.sourceforge.phpdt.core.ISourceReference;
13 import net.sourceforge.phpdt.core.JavaCore;
14 import net.sourceforge.phpdt.core.JavaModelException;
15 import net.sourceforge.phpdt.core.dom.CompilationUnit;
16 import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
17 import net.sourceforge.phpdt.internal.ui.actions.CompositeActionGroup;
18 import net.sourceforge.phpdt.internal.ui.text.ContentAssistPreference;
19 import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions;
20 import net.sourceforge.phpdt.internal.ui.text.PHPPairMatcher;
21 import net.sourceforge.phpdt.internal.ui.text.SmartBackspaceManager;
22 import net.sourceforge.phpdt.internal.ui.text.SmartSemicolonAutoEditStrategy;
23 import net.sourceforge.phpdt.internal.ui.text.java.IJavaReconcilingListener;
24 import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionManager;
25 import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionUI;
26 import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionUI.ExitFlags;
27 import net.sourceforge.phpdt.ui.IWorkingCopyManager;
28 import net.sourceforge.phpdt.ui.PreferenceConstants;
29 import net.sourceforge.phpdt.ui.actions.GenerateActionGroup;
30 import net.sourceforge.phpdt.ui.text.JavaTextTools;
31 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
32 import net.sourceforge.phpeclipse.ui.editor.ShowExternalPreviewAction;
34 import org.eclipse.core.internal.runtime.ListenerList;
35 import org.eclipse.core.resources.IFile;
36 import org.eclipse.core.resources.IWorkspaceRoot;
37 import org.eclipse.core.resources.ResourcesPlugin;
38 import org.eclipse.core.runtime.CoreException;
39 import org.eclipse.core.runtime.IPath;
40 import org.eclipse.core.runtime.IProgressMonitor;
41 import org.eclipse.core.runtime.IStatus;
42 import org.eclipse.core.runtime.Preferences;
43 import org.eclipse.jface.action.Action;
44 import org.eclipse.jface.action.IAction;
45 import org.eclipse.jface.action.IMenuManager;
46 import org.eclipse.jface.dialogs.ErrorDialog;
47 import org.eclipse.jface.dialogs.IMessageProvider;
48 import org.eclipse.jface.dialogs.MessageDialog;
49 import org.eclipse.jface.preference.IPreferenceStore;
50 import org.eclipse.jface.preference.PreferenceConverter;
51 import org.eclipse.jface.text.BadLocationException;
52 import org.eclipse.jface.text.DocumentCommand;
53 import org.eclipse.jface.text.IAutoEditStrategy;
54 import org.eclipse.jface.text.IDocument;
55 import org.eclipse.jface.text.ILineTracker;
56 import org.eclipse.jface.text.IRegion;
57 import org.eclipse.jface.text.ITextOperationTarget;
58 import org.eclipse.jface.text.ITextViewerExtension;
59 import org.eclipse.jface.text.ITypedRegion;
60 import org.eclipse.jface.text.IWidgetTokenKeeper;
61 import org.eclipse.jface.text.contentassist.ContentAssistant;
62 import org.eclipse.jface.text.contentassist.IContentAssistant;
63 import org.eclipse.jface.text.source.IOverviewRuler;
64 import org.eclipse.jface.text.source.ISourceViewer;
65 import org.eclipse.jface.text.source.IVerticalRuler;
66 import org.eclipse.jface.text.source.SourceViewerConfiguration;
67 import org.eclipse.jface.util.PropertyChangeEvent;
68 import org.eclipse.jface.window.Window;
69 import org.eclipse.swt.SWT;
70 import org.eclipse.swt.custom.VerifyKeyListener;
71 import org.eclipse.swt.events.VerifyEvent;
72 import org.eclipse.swt.graphics.Color;
73 import org.eclipse.swt.graphics.Point;
74 import org.eclipse.swt.graphics.RGB;
75 import org.eclipse.swt.widgets.Composite;
76 import org.eclipse.swt.widgets.Display;
77 import org.eclipse.swt.widgets.Shell;
78 import org.eclipse.ui.IEditorInput;
79 import org.eclipse.ui.IEditorPart;
80 import org.eclipse.ui.IFileEditorInput;
81 import org.eclipse.ui.IWorkbenchPage;
82 import org.eclipse.ui.IWorkbenchWindow;
83 import org.eclipse.ui.actions.ActionContext;
84 import org.eclipse.ui.actions.ActionGroup;
85 import org.eclipse.ui.dialogs.SaveAsDialog;
86 import org.eclipse.ui.editors.text.IStorageDocumentProvider;
87 import org.eclipse.ui.help.WorkbenchHelp;
88 import org.eclipse.ui.part.FileEditorInput;
89 import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
90 import org.eclipse.ui.texteditor.ContentAssistAction;
91 import org.eclipse.ui.texteditor.IDocumentProvider;
92 import org.eclipse.ui.texteditor.ITextEditorActionConstants;
93 import org.eclipse.ui.texteditor.TextOperationAction;
95 /*******************************************************************************
96 * Copyright (c) 2000, 2002 IBM Corp. and others. All rights reserved. This
97 * program and the accompanying materials are made available under the terms of
98 * the Common Public License v1.0 which accompanies this distribution, and is
99 * available at http://www.eclipse.org/legal/cpl-v10.html
101 * Contributors: IBM Corporation - Initial implementation Klaus Hartlage -
102 * www.eclipseproject.de
103 ******************************************************************************/
105 * PHP specific text editor.
107 public class PHPUnitEditor extends PHPEditor { //implements
108 // IJavaReconcilingListener {
109 interface ITextConverter {
110 void customizeDocumentCommand(IDocument document, DocumentCommand command);
113 // class AdaptedRulerLayout extends Layout {
115 // protected int fGap;
116 // protected AdaptedSourceViewer fAdaptedSourceViewer;
118 // protected AdaptedRulerLayout(int gap, AdaptedSourceViewer asv) {
120 // fAdaptedSourceViewer = asv;
123 // protected Point computeSize(Composite composite, int wHint, int hHint,
124 // boolean flushCache) {
125 // Control[] children = composite.getChildren();
126 // Point s = children[children.length - 1].computeSize(SWT.DEFAULT,
127 // SWT.DEFAULT, flushCache);
128 // if (fAdaptedSourceViewer.isVerticalRulerVisible())
129 // s.x += fAdaptedSourceViewer.getVerticalRuler().getWidth() + fGap;
133 // protected void layout(Composite composite, boolean flushCache) {
134 // Rectangle clArea = composite.getClientArea();
135 // if (fAdaptedSourceViewer.isVerticalRulerVisible()) {
137 // StyledText textWidget = fAdaptedSourceViewer.getTextWidget();
138 // Rectangle trim = textWidget.computeTrim(0, 0, 0, 0);
139 // int scrollbarHeight = trim.height;
141 // IVerticalRuler vr = fAdaptedSourceViewer.getVerticalRuler();
142 // int vrWidth = vr.getWidth();
145 // if (fAdaptedSourceViewer.isOverviewRulerVisible()) {
146 // OverviewRuler or = fAdaptedSourceViewer.getOverviewRuler();
147 // orWidth = or.getWidth();
148 // or.getControl().setBounds(clArea.width - orWidth, scrollbarHeight,
149 // orWidth, clArea.height - 3 * scrollbarHeight);
152 // textWidget.setBounds(vrWidth + fGap, 0, clArea.width - vrWidth - orWidth
154 // 2 * fGap, clArea.height);
155 // vr.getControl().setBounds(0, 0, vrWidth, clArea.height -
159 // StyledText textWidget = fAdaptedSourceViewer.getTextWidget();
160 // textWidget.setBounds(0, 0, clArea.width, clArea.height);
165 // class AdaptedSourceViewer extends SourceViewer { // extends
166 // JavaCorrectionSourceViewer {
168 // private List fTextConverters;
170 // private OverviewRuler fOverviewRuler;
171 // private boolean fIsOverviewRulerVisible;
172 // /** The viewer's overview ruler hovering controller */
173 // private AbstractHoverInformationControlManager
174 // fOverviewRulerHoveringController;
176 // private boolean fIgnoreTextConverters = false;
178 // private IVerticalRuler fCachedVerticalRuler;
179 // private boolean fCachedIsVerticalRulerVisible;
181 // public AdaptedSourceViewer(Composite parent, IVerticalRuler ruler, int
183 // super(parent, ruler, styles); //, CompilationUnitEditor.this);
185 // fCachedVerticalRuler = ruler;
186 // fCachedIsVerticalRulerVisible = (ruler != null);
187 // fOverviewRuler = new OverviewRuler(VERTICAL_RULER_WIDTH);
189 // delayedCreateControl(parent, styles);
193 // * @see ISourceViewer#showAnnotations(boolean)
195 // public void showAnnotations(boolean show) {
196 // fCachedIsVerticalRulerVisible = (show && fCachedVerticalRuler != null);
197 // // super.showAnnotations(show);
200 // public IContentAssistant getContentAssistant() {
201 // return fContentAssistant;
205 // * @see ITextOperationTarget#doOperation(int)
207 // public void doOperation(int operation) {
209 // if (getTextWidget() == null)
212 // switch (operation) {
213 // case CONTENTASSIST_PROPOSALS :
214 // String msg = fContentAssistant.showPossibleCompletions();
215 // setStatusLineErrorMessage(msg);
218 // fIgnoreTextConverters = true;
221 // fIgnoreTextConverters = true;
225 // super.doOperation(operation);
228 // public void insertTextConverter(ITextConverter textConverter, int index)
230 // throw new UnsupportedOperationException();
233 // public void addTextConverter(ITextConverter textConverter) {
234 // if (fTextConverters == null) {
235 // fTextConverters = new ArrayList(1);
236 // fTextConverters.add(textConverter);
237 // } else if (!fTextConverters.contains(textConverter))
238 // fTextConverters.add(textConverter);
241 // public void removeTextConverter(ITextConverter textConverter) {
242 // if (fTextConverters != null) {
243 // fTextConverters.remove(textConverter);
244 // if (fTextConverters.size() == 0)
245 // fTextConverters = null;
250 // * @see TextViewer#customizeDocumentCommand(DocumentCommand)
252 // protected void customizeDocumentCommand(DocumentCommand command) {
253 // super.customizeDocumentCommand(command);
254 // if (!fIgnoreTextConverters && fTextConverters != null) {
255 // for (Iterator e = fTextConverters.iterator(); e.hasNext();)
256 // ((ITextConverter) e.next()).customizeDocumentCommand(getDocument(),
259 // fIgnoreTextConverters = false;
262 // public IVerticalRuler getVerticalRuler() {
263 // return fCachedVerticalRuler;
266 // public boolean isVerticalRulerVisible() {
267 // return fCachedIsVerticalRulerVisible;
270 // public OverviewRuler getOverviewRuler() {
271 // return fOverviewRuler;
275 // * @see TextViewer#createControl(Composite, int)
277 // protected void createControl(Composite parent, int styles) {
278 // // do nothing here
281 // protected void delayedCreateControl(Composite parent, int styles) {
282 // //create the viewer
283 // super.createControl(parent, styles);
285 // Control control = getControl();
286 // if (control instanceof Composite) {
287 // Composite composite = (Composite) control;
288 // composite.setLayout(new AdaptedRulerLayout(GAP_SIZE, this));
289 // fOverviewRuler.createControl(composite, this);
292 // protected void ensureOverviewHoverManagerInstalled() {
293 // if (fOverviewRulerHoveringController == null && fAnnotationHover != null
294 // && fHoverControlCreator != null) {
295 // fOverviewRulerHoveringController =
296 // new OverviewRulerHoverManager(fOverviewRuler, this, fAnnotationHover,
297 // fHoverControlCreator);
298 // fOverviewRulerHoveringController.install(fOverviewRuler.getControl());
302 // public void hideOverviewRuler() {
303 // fIsOverviewRulerVisible = false;
304 // Control control = getControl();
305 // if (control instanceof Composite) {
306 // Composite composite = (Composite) control;
307 // composite.layout();
309 // if (fOverviewRulerHoveringController != null) {
310 // fOverviewRulerHoveringController.dispose();
311 // fOverviewRulerHoveringController = null;
315 // public void showOverviewRuler() {
316 // fIsOverviewRulerVisible = true;
317 // Control control = getControl();
318 // if (control instanceof Composite) {
319 // Composite composite = (Composite) control;
320 // composite.layout();
322 // ensureOverviewHoverManagerInstalled();
325 // public boolean isOverviewRulerVisible() {
326 // return fIsOverviewRulerVisible;
330 // * @see ISourceViewer#setDocument(IDocument, IAnnotationModel, int, int)
332 // public void setDocument(
333 // IDocument document,
334 // IAnnotationModel annotationModel,
335 // int visibleRegionOffset,
336 // int visibleRegionLength) {
337 // super.setDocument(document, annotationModel, visibleRegionOffset,
338 // visibleRegionLength);
339 // fOverviewRuler.setModel(annotationModel);
342 // // http://dev.eclipse.org/bugs/show_bug.cgi?id=19270
343 // public void updateIndentationPrefixes() {
344 // SourceViewerConfiguration configuration = getSourceViewerConfiguration();
345 // String[] types = configuration.getConfiguredContentTypes(this);
346 // for (int i = 0; i < types.length; i++) {
347 // String[] prefixes = configuration.getIndentPrefixes(this, types[i]);
348 // if (prefixes != null && prefixes.length > 0)
349 // setIndentPrefixes(prefixes, types[i]);
354 // * @see IWidgetTokenOwner#requestWidgetToken(IWidgetTokenKeeper)
356 // public boolean requestWidgetToken(IWidgetTokenKeeper requester) {
357 // if (WorkbenchHelp.isContextHelpDisplayed())
359 // return super.requestWidgetToken(requester);
364 // org.eclipse.jface.text.source.ISourceViewer#configure(org.eclipse.jface.text.source.SourceViewerConfiguration)
366 // public void configure(SourceViewerConfiguration configuration) {
367 // super.configure(configuration);
368 // // prependAutoEditStrategy(new SmartBracesAutoEditStrategy(this),
369 // IDocument.DEFAULT_CONTENT_TYPE);
372 // protected void handleDispose() {
373 // fOverviewRuler = null;
375 // if (fOverviewRulerHoveringController != null) {
376 // fOverviewRulerHoveringController.dispose();
377 // fOverviewRulerHoveringController = null;
380 // super.handleDispose();
384 class AdaptedSourceViewer extends JavaSourceViewer {
385 private List fTextConverters;
387 private boolean fIgnoreTextConverters = false;
389 // private JavaCorrectionAssistant fCorrectionAssistant;
390 public AdaptedSourceViewer(Composite parent, IVerticalRuler verticalRuler,
391 IOverviewRuler overviewRuler, boolean showAnnotationsOverview,
392 int styles, IPreferenceStore store) {
393 super(parent, verticalRuler, overviewRuler, showAnnotationsOverview,
397 // public AdaptedSourceViewer(Composite parent,
398 // IVerticalRuler verticalRuler, IOverviewRuler overviewRuler,
399 // boolean showAnnotationsOverview, int styles) {
400 // super(parent, verticalRuler, overviewRuler,
401 // showAnnotationsOverview, styles);
403 public IContentAssistant getContentAssistant() {
404 return fContentAssistant;
408 * @see ITextOperationTarget#doOperation(int)
410 public void doOperation(int operation) {
411 if (getTextWidget() == null)
414 case CONTENTASSIST_PROPOSALS:
415 String msg = fContentAssistant.showPossibleCompletions();
416 setStatusLineErrorMessage(msg);
418 // case CORRECTIONASSIST_PROPOSALS:
419 // fCorrectionAssistant.showPossibleCompletions();
422 fIgnoreTextConverters = true;
425 fIgnoreTextConverters = true;
428 super.doOperation(operation);
432 * @see ITextOperationTarget#canDoOperation(int)
434 public boolean canDoOperation(int operation) {
435 // if (operation == CORRECTIONASSIST_PROPOSALS)
436 // return isEditable();
437 return super.canDoOperation(operation);
441 * @see TextViewer#handleDispose()
443 protected void handleDispose() {
444 // if (fCorrectionAssistant != null) {
445 // fCorrectionAssistant.uninstall();
446 // fCorrectionAssistant= null;
448 super.handleDispose();
451 public void insertTextConverter(ITextConverter textConverter, int index) {
452 throw new UnsupportedOperationException();
455 public void addTextConverter(ITextConverter textConverter) {
456 if (fTextConverters == null) {
457 fTextConverters = new ArrayList(1);
458 fTextConverters.add(textConverter);
459 } else if (!fTextConverters.contains(textConverter))
460 fTextConverters.add(textConverter);
463 public void removeTextConverter(ITextConverter textConverter) {
464 if (fTextConverters != null) {
465 fTextConverters.remove(textConverter);
466 if (fTextConverters.size() == 0)
467 fTextConverters = null;
472 * @see TextViewer#customizeDocumentCommand(DocumentCommand)
474 protected void customizeDocumentCommand(DocumentCommand command) {
475 super.customizeDocumentCommand(command);
476 if (!fIgnoreTextConverters && fTextConverters != null) {
477 for (Iterator e = fTextConverters.iterator(); e.hasNext();)
478 ((ITextConverter) e.next()).customizeDocumentCommand(getDocument(),
481 fIgnoreTextConverters = false;
484 // http://dev.eclipse.org/bugs/show_bug.cgi?id=19270
485 public void updateIndentationPrefixes() {
486 SourceViewerConfiguration configuration = getSourceViewerConfiguration();
487 String[] types = configuration.getConfiguredContentTypes(this);
488 for (int i = 0; i < types.length; i++) {
489 String[] prefixes = configuration.getIndentPrefixes(this, types[i]);
490 if (prefixes != null && prefixes.length > 0)
491 setIndentPrefixes(prefixes, types[i]);
496 * @see IWidgetTokenOwner#requestWidgetToken(IWidgetTokenKeeper)
498 public boolean requestWidgetToken(IWidgetTokenKeeper requester) {
499 if (WorkbenchHelp.isContextHelpDisplayed())
501 return super.requestWidgetToken(requester);
505 // * @see org.eclipse.jface.text.source.ISourceViewer#configure(org.eclipse.jface.text.source.SourceViewerConfiguration)
507 // public void configure(SourceViewerConfiguration configuration) {
508 // super.configure(configuration);
509 // // fCorrectionAssistant= new
510 // // JavaCorrectionAssistant(CompilationUnitEditor.this);
511 // // fCorrectionAssistant.install(this);
512 // //TODO install SmartBracesAutoEditStrategy
513 // // prependAutoEditStrategy(new SmartBracesAutoEditStrategy(this),
514 // // IDocument.DEFAULT_CONTENT_TYPE);
516 public void configure(SourceViewerConfiguration configuration) {
517 super.configure(configuration);
518 // fCorrectionAssistant= new JavaCorrectionAssistant(CompilationUnitEditor.this);
519 // fCorrectionAssistant.install(this);
520 IAutoEditStrategy smartSemi= new SmartSemicolonAutoEditStrategy(IPHPPartitions.PHP_PARTITIONING);
521 prependAutoEditStrategy(smartSemi, IDocument.DEFAULT_CONTENT_TYPE);
522 prependAutoEditStrategy(smartSemi, IPHPPartitions.PHP_STRING_DQ);
523 prependAutoEditStrategy(smartSemi, IPHPPartitions.PHP_STRING_SQ);
524 // prependAutoEditStrategy(smartSemi, IPHPPartitions.JAVA_CHARACTER);
528 * Remembers data related to the current selection to be able to
533 private class RememberedSelection {
534 /** The remembered selection start. */
535 private RememberedOffset fStartOffset= new RememberedOffset();
536 /** The remembered selection end. */
537 private RememberedOffset fEndOffset= new RememberedOffset();
540 * Remember current selection.
542 public void remember() {
543 /* https://bugs.eclipse.org/bugs/show_bug.cgi?id=52257
544 * This method may be called inside an async call posted
545 * to the UI thread, so protect against intermediate disposal
548 ISourceViewer viewer= getSourceViewer();
549 if (viewer != null) {
550 IRegion selection= getSignedSelection(viewer);
551 int startOffset= selection.getOffset();
552 int endOffset= startOffset + selection.getLength();
554 fStartOffset.setOffset(startOffset);
555 fEndOffset.setOffset(endOffset);
560 * Restore remembered selection.
562 public void restore() {
563 /* https://bugs.eclipse.org/bugs/show_bug.cgi?id=52257
564 * This method may be called inside an async call posted
565 * to the UI thread, so protect against intermediate disposal
568 if (getSourceViewer() == null)
573 int startOffset, endOffset;
574 int revealStartOffset, revealEndOffset;
575 if (showsHighlightRangeOnly()) {
576 IJavaElement newStartElement= fStartOffset.getElement();
577 startOffset= fStartOffset.getRememberedOffset(newStartElement);
578 revealStartOffset= fStartOffset.getRevealOffset(newStartElement, startOffset);
579 if (revealStartOffset == -1)
582 IJavaElement newEndElement= fEndOffset.getElement();
583 endOffset= fEndOffset.getRememberedOffset(newEndElement);
584 revealEndOffset= fEndOffset.getRevealOffset(newEndElement, endOffset);
585 if (revealEndOffset == -1)
588 startOffset= fStartOffset.getOffset();
589 revealStartOffset= startOffset;
590 endOffset= fEndOffset.getOffset();
591 revealEndOffset= endOffset;
594 if (startOffset == -1) {
595 startOffset= endOffset; // fallback to caret offset
596 revealStartOffset= revealEndOffset;
599 if (endOffset == -1) {
600 endOffset= startOffset; // fallback to other offset
601 revealEndOffset= revealStartOffset;
604 IJavaElement element;
605 if (endOffset == -1) {
606 // fallback to element selection
607 element= fEndOffset.getElement();
609 element= fStartOffset.getElement();
611 setSelection(element);
615 if (isValidSelection(revealStartOffset, revealEndOffset - revealStartOffset) && isValidSelection(startOffset, endOffset - startOffset))
616 selectAndReveal(startOffset, endOffset - startOffset, revealStartOffset, revealEndOffset - revealStartOffset);
618 fStartOffset.clear();
623 private boolean isValidSelection(int offset, int length) {
624 IDocumentProvider provider= getDocumentProvider();
625 if (provider != null) {
626 IDocument document= provider.getDocument(getEditorInput());
627 if (document != null) {
628 int end= offset + length;
629 int documentLength= document.getLength();
630 return 0 <= offset && offset <= documentLength && 0 <= end && end <= documentLength;
639 * Remembers additional data for a given
640 * offset to be able restore it later.
644 private class RememberedOffset {
645 /** Remembered line for the given offset */
647 /** Remembered column for the given offset*/
649 /** Remembered Java element for the given offset*/
650 private IJavaElement fElement;
651 /** Remembered Java element line for the given offset*/
652 private int fElementLine;
655 * Store visual properties of the given offset.
657 * @param offset Offset in the document
659 public void setOffset(int offset) {
661 IDocument document= getSourceViewer().getDocument();
662 fLine= document.getLineOfOffset(offset);
663 fColumn= offset - document.getLineOffset(fLine);
664 fElement= getElementAt(offset, true);
667 if (fElement instanceof IMember) {
668 ISourceRange range= ((IMember) fElement).getNameRange();
670 fElementLine= document.getLineOfOffset(range.getOffset());
672 if (fElementLine == -1)
673 fElementLine= document.getLineOfOffset(getOffset(fElement));
674 } catch (BadLocationException e) {
676 PHPeclipsePlugin.log(e);
678 } catch (JavaModelException e) {
680 PHPeclipsePlugin.log(e.getStatus());
686 * Return offset recomputed from stored visual properties.
688 * @return Offset in the document
690 public int getOffset() {
691 IJavaElement newElement= getElement();
693 int offset= getRememberedOffset(newElement);
695 if (offset != -1 && !containsOffset(newElement, offset) && (offset == 0 || !containsOffset(newElement, offset - 1)))
702 * Return offset recomputed from stored visual properties.
704 * @param newElement Enclosing element
705 * @return Offset in the document
707 public int getRememberedOffset(IJavaElement newElement) {
709 if (newElement == null)
712 IDocument document= getSourceViewer().getDocument();
713 int newElementLine= -1;
714 if (newElement instanceof IMember) {
715 ISourceRange range= ((IMember) newElement).getNameRange();
717 newElementLine= document.getLineOfOffset(range.getOffset());
719 if (newElementLine == -1)
720 newElementLine= document.getLineOfOffset(getOffset(newElement));
721 if (newElementLine == -1)
724 int newLine= fLine + newElementLine - fElementLine;
725 if (newLine < 0 || newLine >= document.getNumberOfLines())
727 int maxColumn= document.getLineLength(newLine);
728 String lineDelimiter= document.getLineDelimiter(newLine);
729 if (lineDelimiter != null)
730 maxColumn= maxColumn - lineDelimiter.length();
732 if (fColumn > maxColumn)
733 offset= document.getLineOffset(newLine) + maxColumn;
735 offset= document.getLineOffset(newLine) + fColumn;
738 } catch (BadLocationException e) {
740 PHPeclipsePlugin.log(e);
742 } catch (JavaModelException e) {
744 PHPeclipsePlugin.log(e.getStatus());
750 * Returns the offset used to reveal the given element based on the given selection offset.
751 * @param element the element
752 * @param offset the selection offset
753 * @return the offset to reveal the given element based on the given selection offset
755 public int getRevealOffset(IJavaElement element, int offset) {
756 if (element == null || offset == -1)
759 if (containsOffset(element, offset)) {
761 IJavaElement alternateElement= getElementAt(offset, false);
762 if (element.getHandleIdentifier().equals(alternateElement.getParent().getHandleIdentifier()))
763 return offset - 1; // Solves test case 2 from https://bugs.eclipse.org/bugs/show_bug.cgi?id=47727#c3
766 } else if (offset > 0 && containsOffset(element, offset - 1))
767 return offset - 1; // Solves test case 1 from https://bugs.eclipse.org/bugs/show_bug.cgi?id=47727#c3
773 * Return Java element recomputed from stored visual properties.
775 * @return Java element
777 public IJavaElement getElement() {
778 if (fElement == null)
781 return findElement(fElement);
785 * Clears the stored position
787 public void clear() {
795 * Does the given Java element contain the given offset?
796 * @param element Java element
797 * @param offset Offset
798 * @return <code>true</code> iff the Java element contains the offset
800 private boolean containsOffset(IJavaElement element, int offset) {
801 int elementOffset= getOffset(element);
802 int elementLength= getLength(element);
803 return (elementOffset > -1 && elementLength > -1) ? (offset >= elementOffset && offset < elementOffset + elementLength) : false;
806 * Returns the offset of the given Java element.
808 * @param element Java element
809 * @return Offset of the given Java element
811 private int getOffset(IJavaElement element) {
812 if (element instanceof ISourceReference) {
813 ISourceReference sr= (ISourceReference) element;
815 ISourceRange srcRange= sr.getSourceRange();
816 if (srcRange != null)
817 return srcRange.getOffset();
818 } catch (JavaModelException e) {
825 * Returns the length of the given Java element.
827 * @param element Java element
828 * @return Length of the given Java element
830 private int getLength(IJavaElement element) {
831 if (element instanceof ISourceReference) {
832 ISourceReference sr= (ISourceReference) element;
834 ISourceRange srcRange= sr.getSourceRange();
835 if (srcRange != null)
836 return srcRange.getLength();
837 } catch (JavaModelException e) {
844 * Returns the updated java element for the old java element.
846 * @param element Old Java element
847 * @return Updated Java element
849 private IJavaElement findElement(IJavaElement element) {
854 IWorkingCopyManager manager= PHPeclipsePlugin.getDefault().getWorkingCopyManager();
855 ICompilationUnit unit= manager.getWorkingCopy(getEditorInput());
860 synchronized (unit) {
861 // unit.reconcile(ICompilationUnit.NO_AST, false, null, null);
864 IJavaElement[] findings= unit.findElements(element);
865 if (findings != null && findings.length > 0)
868 } catch (JavaModelException x) {
869 PHPeclipsePlugin.log(x.getStatus());
870 // nothing found, be tolerant and go on
879 static class TabConverter implements ITextConverter {
880 private int fTabRatio;
882 private ILineTracker fLineTracker;
884 public TabConverter() {
887 public void setNumberOfSpacesPerTab(int ratio) {
891 public void setLineTracker(ILineTracker lineTracker) {
892 fLineTracker = lineTracker;
895 private int insertTabString(StringBuffer buffer, int offsetInLine) {
898 int remainder = offsetInLine % fTabRatio;
899 remainder = fTabRatio - remainder;
900 for (int i = 0; i < remainder; i++)
905 public void customizeDocumentCommand(IDocument document,
906 DocumentCommand command) {
907 String text = command.text;
910 int index = text.indexOf('\t');
912 StringBuffer buffer = new StringBuffer();
913 fLineTracker.set(command.text);
914 int lines = fLineTracker.getNumberOfLines();
916 for (int i = 0; i < lines; i++) {
917 int offset = fLineTracker.getLineOffset(i);
918 int endOffset = offset + fLineTracker.getLineLength(i);
919 String line = text.substring(offset, endOffset);
922 IRegion firstLine = document
923 .getLineInformationOfOffset(command.offset);
924 position = command.offset - firstLine.getOffset();
926 int length = line.length();
927 for (int j = 0; j < length; j++) {
928 char c = line.charAt(j);
930 position += insertTabString(buffer, position);
937 command.text = buffer.toString();
938 } catch (BadLocationException x) {
944 private static class ExitPolicy implements LinkedPositionUI.ExitPolicy {
945 final char fExitCharacter;
947 public ExitPolicy(char exitCharacter) {
948 fExitCharacter = exitCharacter;
952 * @see org.phpeclipse.phpdt.internal.ui.text.link.LinkedPositionUI.ExitPolicy#doExit(org.phpeclipse.phpdt.internal.ui.text.link.LinkedPositionManager,
953 * org.eclipse.swt.events.VerifyEvent, int, int)
955 public ExitFlags doExit(LinkedPositionManager manager, VerifyEvent event,
956 int offset, int length) {
957 if (event.character == fExitCharacter) {
958 if (manager.anyPositionIncludes(offset, length))
959 return new ExitFlags(LinkedPositionUI.COMMIT
960 | LinkedPositionUI.UPDATE_CARET, false);
962 return new ExitFlags(LinkedPositionUI.COMMIT, true);
964 switch (event.character) {
966 if (manager.getFirstPosition().length == 0)
967 return new ExitFlags(0, false);
972 return new ExitFlags(LinkedPositionUI.COMMIT, true);
979 private static class BracketLevel {
984 LinkedPositionManager fManager;
986 LinkedPositionUI fEditor;
989 private class BracketInserter implements VerifyKeyListener,
990 LinkedPositionUI.ExitListener {
991 private boolean fCloseBracketsPHP = true;
993 private boolean fCloseStringsPHP = true;
995 private boolean fCloseBracketsHTML = true;
997 private boolean fCloseStringsHTML = true;
1001 private int fLength;
1003 public void setCloseBracketsPHPEnabled(boolean enabled) {
1004 fCloseBracketsPHP = enabled;
1007 public void setCloseStringsPHPEnabled(boolean enabled) {
1008 fCloseStringsPHP = enabled;
1011 public void setCloseBracketsHTMLEnabled(boolean enabled) {
1012 fCloseBracketsHTML = enabled;
1015 public void setCloseStringsHTMLEnabled(boolean enabled) {
1016 fCloseStringsHTML = enabled;
1019 private boolean hasIdentifierToTheRight(IDocument document, int offset) {
1022 IRegion endLine = document.getLineInformationOfOffset(end);
1023 int maxEnd = endLine.getOffset() + endLine.getLength();
1024 while (end != maxEnd && Character.isWhitespace(document.getChar(end)))
1026 return end != maxEnd
1027 && Scanner.isPHPIdentifierPart(document.getChar(end));
1028 } catch (BadLocationException e) {
1034 private boolean hasIdentifierToTheLeft(IDocument document, int offset) {
1037 IRegion startLine = document.getLineInformationOfOffset(start);
1038 int minStart = startLine.getOffset();
1039 while (start != minStart
1040 && Character.isWhitespace(document.getChar(start - 1)))
1042 return start != minStart
1043 && Scanner.isPHPIdentifierPart(document.getChar(start - 1));
1044 } catch (BadLocationException e) {
1049 private boolean hasCharacterToTheRight(IDocument document, int offset,
1053 IRegion endLine = document.getLineInformationOfOffset(end);
1054 int maxEnd = endLine.getOffset() + endLine.getLength();
1055 while (end != maxEnd && Character.isWhitespace(document.getChar(end)))
1057 return end != maxEnd && document.getChar(end) == character;
1058 } catch (BadLocationException e) {
1065 * @see org.eclipse.swt.custom.VerifyKeyListener#verifyKey(org.eclipse.swt.events.VerifyEvent)
1067 public void verifyKey(VerifyEvent event) {
1070 final ISourceViewer sourceViewer = getSourceViewer();
1071 IDocument document = sourceViewer.getDocument();
1072 final Point selection = sourceViewer.getSelectedRange();
1073 final int offset = selection.x;
1074 final int length = selection.y;
1076 ITypedRegion partition = document.getPartition(offset);
1077 String type = partition.getType();
1078 if (type.equals(IPHPPartitions.PHP_PARTITIONING)) {
1079 switch (event.character) {
1081 if (hasCharacterToTheRight(document, offset + length, '('))
1085 if (!fCloseBracketsPHP)
1087 if (hasIdentifierToTheRight(document, offset + length))
1091 if (event.character == '"') {
1092 if (!fCloseStringsPHP)
1094 // changed for statements like echo "" print ""
1095 // if (hasIdentifierToTheLeft(document, offset)
1097 // hasIdentifierToTheRight(document, offset +
1099 if (hasIdentifierToTheRight(document, offset + length))
1102 // ITypedRegion partition=
1103 // document.getPartition(offset);
1105 // IDocument.DEFAULT_CONTENT_TYPE.equals(partition.getType())
1107 // (partition.getOffset() != offset))
1109 final char character = event.character;
1110 final char closingCharacter = getPeerCharacter(character);
1111 final StringBuffer buffer = new StringBuffer();
1112 buffer.append(character);
1113 buffer.append(closingCharacter);
1114 document.replace(offset, length, buffer.toString());
1115 LinkedPositionManager manager = new LinkedPositionManager(document);
1116 manager.addPosition(offset + 1, 0);
1119 LinkedPositionUI editor = new LinkedPositionUI(sourceViewer,
1121 editor.setCancelListener(this);
1122 editor.setExitPolicy(new ExitPolicy(closingCharacter));
1123 editor.setFinalCaretOffset(offset + 2);
1125 IRegion newSelection = editor.getSelectedRegion();
1126 sourceViewer.setSelectedRange(newSelection.getOffset(),
1127 newSelection.getLength());
1130 } else if (type.equals(IPHPPartitions.HTML)
1131 || type.equals(IDocument.DEFAULT_CONTENT_TYPE)) {
1132 switch (event.character) {
1134 if (hasCharacterToTheRight(document, offset + length, '('))
1138 if (!fCloseBracketsHTML)
1140 if (hasIdentifierToTheRight(document, offset + length))
1144 if (event.character == '"') {
1145 if (!fCloseStringsHTML)
1147 if (hasIdentifierToTheLeft(document, offset)
1148 || hasIdentifierToTheRight(document, offset + length))
1151 // ITypedRegion partition=
1152 // document.getPartition(offset);
1154 // IDocument.DEFAULT_CONTENT_TYPE.equals(partition.getType())
1156 // (partition.getOffset() != offset))
1158 final char character = event.character;
1159 final char closingCharacter = getPeerCharacter(character);
1160 final StringBuffer buffer = new StringBuffer();
1161 buffer.append(character);
1162 buffer.append(closingCharacter);
1163 document.replace(offset, length, buffer.toString());
1164 LinkedPositionManager manager = new LinkedPositionManager(document);
1165 manager.addPosition(offset + 1, 0);
1168 LinkedPositionUI editor = new LinkedPositionUI(sourceViewer,
1170 editor.setCancelListener(this);
1171 editor.setExitPolicy(new ExitPolicy(closingCharacter));
1172 editor.setFinalCaretOffset(offset + 2);
1174 IRegion newSelection = editor.getSelectedRegion();
1175 sourceViewer.setSelectedRange(newSelection.getOffset(),
1176 newSelection.getLength());
1180 } catch (BadLocationException e) {
1185 * @see org.phpeclipse.phpdt.internal.ui.text.link.LinkedPositionUI.ExitListener#exit(boolean)
1187 public void exit(boolean accept) {
1192 final ISourceViewer sourceViewer = getSourceViewer();
1193 IDocument document = sourceViewer.getDocument();
1194 document.replace(fOffset, fLength, null);
1195 } catch (BadLocationException e) {
1200 /** The editor's save policy */
1201 protected ISavePolicy fSavePolicy;
1204 * Listener to annotation model changes that updates the error tick in the tab
1207 private JavaEditorErrorTickUpdater fJavaEditorErrorTickUpdater;
1209 /** The editor's paint manager */
1210 // private PaintManager fPaintManager;
1211 /** The editor's bracket painter */
1212 private BracketPainter fBracketPainter;
1214 /** The editor's bracket matcher */
1215 private PHPPairMatcher fBracketMatcher;
1217 /** The editor's line painter */
1218 private LinePainter fLinePainter;
1220 /** The editor's print margin ruler painter */
1221 private PrintMarginPainter fPrintMarginPainter;
1223 /** The editor's problem painter */
1224 // private ProblemPainter fProblemPainter;
1225 /** The editor's tab converter */
1226 private TabConverter fTabConverter;
1228 /** History for structure select action */
1229 //private SelectionHistory fSelectionHistory;
1230 /** The preference property change listener for php core. */
1231 // private IPropertyChangeListener fPropertyChangeListener = new
1232 // PropertyChangeListener();
1233 /** The remembered java element */
1234 private IJavaElement fRememberedElement;
1237 * The remembered selection.
1240 private RememberedSelection fRememberedSelection= new RememberedSelection();
1243 /** The remembered php element offset */
1244 private int fRememberedElementOffset;
1246 /** The bracket inserter. */
1247 private BracketInserter fBracketInserter = new BracketInserter();
1249 /** The standard action groups added to the menu */
1250 private GenerateActionGroup fGenerateActionGroup;
1252 private CompositeActionGroup fContextMenuGroup;
1254 // private class PropertyChangeListener implements IPropertyChangeListener {
1256 // * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
1259 // propertyChange(org.eclipse.core.runtime.Preferences.PropertyChangeEvent
1261 // handlePreferencePropertyChanged(event);
1264 /* Preference key for code formatter tab size */
1265 private final static String CODE_FORMATTER_TAB_SIZE = JavaCore.FORMATTER_TAB_SIZE;
1267 /** Preference key for matching brackets */
1268 private final static String MATCHING_BRACKETS = PreferenceConstants.EDITOR_MATCHING_BRACKETS;
1270 /** Preference key for matching brackets color */
1271 private final static String MATCHING_BRACKETS_COLOR = PreferenceConstants.EDITOR_MATCHING_BRACKETS_COLOR;
1273 /** Preference key for highlighting current line */
1274 private final static String CURRENT_LINE = PreferenceConstants.EDITOR_CURRENT_LINE;
1276 /** Preference key for highlight color of current line */
1277 private final static String CURRENT_LINE_COLOR = PreferenceConstants.EDITOR_CURRENT_LINE_COLOR;
1279 /** Preference key for showing print marging ruler */
1280 private final static String PRINT_MARGIN = PreferenceConstants.EDITOR_PRINT_MARGIN;
1282 /** Preference key for print margin ruler color */
1283 private final static String PRINT_MARGIN_COLOR = PreferenceConstants.EDITOR_PRINT_MARGIN_COLOR;
1285 /** Preference key for print margin ruler column */
1286 private final static String PRINT_MARGIN_COLUMN = PreferenceConstants.EDITOR_PRINT_MARGIN_COLUMN;
1288 /** Preference key for inserting spaces rather than tabs */
1289 private final static String SPACES_FOR_TABS = PreferenceConstants.EDITOR_SPACES_FOR_TABS;
1291 /** Preference key for error indication */
1292 // private final static String ERROR_INDICATION =
1293 // PreferenceConstants.EDITOR_PROBLEM_INDICATION;
1294 /** Preference key for error color */
1295 // private final static String ERROR_INDICATION_COLOR =
1296 // PreferenceConstants.EDITOR_PROBLEM_INDICATION_COLOR;
1297 /** Preference key for warning indication */
1298 // private final static String WARNING_INDICATION =
1299 // PreferenceConstants.EDITOR_WARNING_INDICATION;
1300 /** Preference key for warning color */
1301 // private final static String WARNING_INDICATION_COLOR =
1302 // PreferenceConstants.EDITOR_WARNING_INDICATION_COLOR;
1303 /** Preference key for task indication */
1304 private final static String TASK_INDICATION = PreferenceConstants.EDITOR_TASK_INDICATION;
1306 /** Preference key for task color */
1307 private final static String TASK_INDICATION_COLOR = PreferenceConstants.EDITOR_TASK_INDICATION_COLOR;
1309 /** Preference key for bookmark indication */
1310 private final static String BOOKMARK_INDICATION = PreferenceConstants.EDITOR_BOOKMARK_INDICATION;
1312 /** Preference key for bookmark color */
1313 private final static String BOOKMARK_INDICATION_COLOR = PreferenceConstants.EDITOR_BOOKMARK_INDICATION_COLOR;
1315 /** Preference key for search result indication */
1316 private final static String SEARCH_RESULT_INDICATION = PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION;
1318 /** Preference key for search result color */
1319 private final static String SEARCH_RESULT_INDICATION_COLOR = PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION_COLOR;
1321 /** Preference key for unknown annotation indication */
1322 private final static String UNKNOWN_INDICATION = PreferenceConstants.EDITOR_UNKNOWN_INDICATION;
1324 /** Preference key for unknown annotation color */
1325 private final static String UNKNOWN_INDICATION_COLOR = PreferenceConstants.EDITOR_UNKNOWN_INDICATION_COLOR;
1327 /** Preference key for linked position color */
1328 private final static String LINKED_POSITION_COLOR = PreferenceConstants.EDITOR_LINKED_POSITION_COLOR;
1330 /** Preference key for shwoing the overview ruler */
1331 private final static String OVERVIEW_RULER = PreferenceConstants.EDITOR_OVERVIEW_RULER;
1333 /** Preference key for error indication in overview ruler */
1334 private final static String ERROR_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_ERROR_INDICATION_IN_OVERVIEW_RULER;
1336 /** Preference key for warning indication in overview ruler */
1337 private final static String WARNING_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_WARNING_INDICATION_IN_OVERVIEW_RULER;
1339 /** Preference key for task indication in overview ruler */
1340 private final static String TASK_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_TASK_INDICATION_IN_OVERVIEW_RULER;
1342 /** Preference key for bookmark indication in overview ruler */
1343 private final static String BOOKMARK_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_BOOKMARK_INDICATION_IN_OVERVIEW_RULER;
1345 /** Preference key for search result indication in overview ruler */
1346 private final static String SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER;
1348 /** Preference key for unknown annotation indication in overview ruler */
1349 private final static String UNKNOWN_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_UNKNOWN_INDICATION_IN_OVERVIEW_RULER;
1351 /** Preference key for automatically closing strings */
1352 private final static String CLOSE_STRINGS_PHP = PreferenceConstants.EDITOR_CLOSE_STRINGS_PHP;
1354 /** Preference key for automatically wrapping Java strings */
1355 private final static String WRAP_STRINGS = PreferenceConstants.EDITOR_WRAP_STRINGS;
1357 /** Preference key for automatically closing brackets and parenthesis */
1358 private final static String CLOSE_BRACKETS_PHP = PreferenceConstants.EDITOR_CLOSE_BRACKETS_PHP;
1360 /** Preference key for automatically closing phpdocs and comments */
1361 private final static String CLOSE_JAVADOCS = PreferenceConstants.EDITOR_CLOSE_JAVADOCS;
1363 /** Preference key for automatically adding phpdoc tags */
1364 private final static String ADD_JAVADOC_TAGS = PreferenceConstants.EDITOR_ADD_JAVADOC_TAGS;
1366 /** Preference key for automatically formatting phpdocs */
1367 private final static String FORMAT_JAVADOCS = PreferenceConstants.EDITOR_FORMAT_JAVADOCS;
1369 /** Preference key for automatically closing strings */
1370 private final static String CLOSE_STRINGS_HTML = PreferenceConstants.EDITOR_CLOSE_STRINGS_HTML;
1372 /** Preference key for automatically closing brackets and parenthesis */
1373 private final static String CLOSE_BRACKETS_HTML = PreferenceConstants.EDITOR_CLOSE_BRACKETS_HTML;
1375 /** Preference key for smart paste */
1376 private final static String SMART_PASTE = PreferenceConstants.EDITOR_SMART_PASTE;
1378 // private final static class AnnotationInfo {
1379 // public String fColorPreference;
1380 // public String fOverviewRulerPreference;
1381 // public String fEditorPreference;
1383 // private final static Map ANNOTATION_MAP;
1386 // AnnotationInfo info;
1387 // ANNOTATION_MAP = new HashMap();
1389 // info = new AnnotationInfo();
1390 // info.fColorPreference = TASK_INDICATION_COLOR;
1391 // info.fOverviewRulerPreference = TASK_INDICATION_IN_OVERVIEW_RULER;
1392 // info.fEditorPreference = TASK_INDICATION;
1393 // ANNOTATION_MAP.put(AnnotationType.TASK, info);
1395 // info = new AnnotationInfo();
1396 // info.fColorPreference = ERROR_INDICATION_COLOR;
1397 // info.fOverviewRulerPreference = ERROR_INDICATION_IN_OVERVIEW_RULER;
1398 // info.fEditorPreference = ERROR_INDICATION;
1399 // ANNOTATION_MAP.put(AnnotationType.ERROR, info);
1401 // info = new AnnotationInfo();
1402 // info.fColorPreference = WARNING_INDICATION_COLOR;
1403 // info.fOverviewRulerPreference = WARNING_INDICATION_IN_OVERVIEW_RULER;
1404 // info.fEditorPreference = WARNING_INDICATION;
1405 // ANNOTATION_MAP.put(AnnotationType.WARNING, info);
1407 // info = new AnnotationInfo();
1408 // info.fColorPreference = BOOKMARK_INDICATION_COLOR;
1409 // info.fOverviewRulerPreference = BOOKMARK_INDICATION_IN_OVERVIEW_RULER;
1410 // info.fEditorPreference = BOOKMARK_INDICATION;
1411 // ANNOTATION_MAP.put(AnnotationType.BOOKMARK, info);
1413 // info = new AnnotationInfo();
1414 // info.fColorPreference = SEARCH_RESULT_INDICATION_COLOR;
1415 // info.fOverviewRulerPreference =
1416 // SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER;
1417 // info.fEditorPreference = SEARCH_RESULT_INDICATION;
1418 // ANNOTATION_MAP.put(AnnotationType.SEARCH, info);
1420 // info = new AnnotationInfo();
1421 // info.fColorPreference = UNKNOWN_INDICATION_COLOR;
1422 // info.fOverviewRulerPreference = UNKNOWN_INDICATION_IN_OVERVIEW_RULER;
1423 // info.fEditorPreference = UNKNOWN_INDICATION;
1424 // ANNOTATION_MAP.put(AnnotationType.UNKNOWN, info);
1427 // private final static AnnotationType[] ANNOTATION_LAYERS =
1428 // new AnnotationType[] {
1429 // AnnotationType.UNKNOWN,
1430 // AnnotationType.BOOKMARK,
1431 // AnnotationType.TASK,
1432 // AnnotationType.SEARCH,
1433 // AnnotationType.WARNING,
1434 // AnnotationType.ERROR };
1436 * Creates a new php unit editor.
1440 * Reconciling listeners.
1443 private ListenerList fReconcilingListeners= new ListenerList();
1446 * Mutex for the reconciler. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=63898
1447 * for a description of the problem.
1449 * TODO remove once the underlying problem is solved.
1452 private final Object fReconcilerLock= new Object();
1454 public PHPUnitEditor() {
1456 setDocumentProvider(PHPeclipsePlugin.getDefault()
1457 .getCompilationUnitDocumentProvider());
1458 setEditorContextMenuId("#PHPEditorContext"); //$NON-NLS-1$
1459 setRulerContextMenuId("#PHPRulerContext"); //$NON-NLS-1$
1460 setOutlinerContextMenuId("#PHPOutlinerContext"); //$NON-NLS-1$
1461 // don't set help contextId, we install our own help context
1463 fJavaEditorErrorTickUpdater = new JavaEditorErrorTickUpdater(this);
1467 * @see AbstractTextEditor#createActions()
1469 protected void createActions() {
1470 super.createActions();
1472 // Action action= new
1473 // TextOperationAction(PHPEditorMessages.getResourceBundle(),
1474 // "CorrectionAssistProposal.", this, CORRECTIONASSIST_PROPOSALS);
1476 // action.setActionDefinitionId(PHPEditorActionDefinitionIds.CORRECTION_ASSIST_PROPOSALS);
1477 // setAction("CorrectionAssistProposal", action); //$NON-NLS-1$
1478 // markAsStateDependentAction("CorrectionAssistProposal", true);
1480 //// WorkbenchHelp.setHelp(action,
1481 // IJavaHelpContextIds.QUICK_FIX_ACTION);
1482 action = new ContentAssistAction(PHPEditorMessages.getResourceBundle(),
1483 "ContentAssistProposal.", this); //$NON-NLS-1$
1485 .setActionDefinitionId(PHPEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
1486 setAction("ContentAssistProposal", action); //$NON-NLS-1$
1487 markAsStateDependentAction("ContentAssistProposal", true); //$NON-NLS-1$
1488 // WorkbenchHelp.setHelp(action,
1489 // IJavaHelpContextIds.CONTENT_ASSIST_ACTION);
1490 // action = new TextOperationAction(PHPEditorMessages.getResourceBundle(),
1491 // "ContentAssistContextInformation.", this,
1492 // ISourceViewer.CONTENTASSIST_CONTEXT_INFORMATION); //$NON-NLS-1$
1494 // .setActionDefinitionId(PHPEditorActionDefinitionIds.CONTENT_ASSIST_CONTEXT_INFORMATION);
1495 // setAction("ContentAssistContextInformation", action); //$NON-NLS-1$
1496 // markAsStateDependentAction("ContentAssistContextInformation", true);
1498 // WorkbenchHelp.setHelp(action,
1499 // IJavaHelpContextIds.PARAMETER_HINTS_ACTION);
1501 // TextOperationAction(PHPEditorMessages.getResourceBundle(),
1502 // "ContentAssistCompletePrefix.", this, CONTENTASSIST_COMPLETE_PREFIX);
1504 // action.setActionDefinitionId(PHPEditorActionDefinitionIds.CONTENT_ASSIST_COMPLETE_PREFIX);
1505 // setAction("ContentAssistCompletePrefix", action); //$NON-NLS-1$
1506 // markAsStateDependentAction("ContentAssistCompletePrefix", true);
1508 //// WorkbenchHelp.setHelp(action,
1509 // IJavaHelpContextIds.PARAMETER_HINTS_ACTION);
1510 action = new TextOperationAction(PHPEditorMessages.getResourceBundle(),
1511 "Comment.", this, ITextOperationTarget.PREFIX); //$NON-NLS-1$
1512 action.setActionDefinitionId(PHPEditorActionDefinitionIds.COMMENT);
1513 setAction("Comment", action); //$NON-NLS-1$
1514 markAsStateDependentAction("Comment", true); //$NON-NLS-1$
1515 // WorkbenchHelp.setHelp(action, IJavaHelpContextIds.COMMENT_ACTION);
1516 action = new TextOperationAction(PHPEditorMessages.getResourceBundle(),
1517 "Uncomment.", this, ITextOperationTarget.STRIP_PREFIX); //$NON-NLS-1$
1518 action.setActionDefinitionId(PHPEditorActionDefinitionIds.UNCOMMENT);
1519 setAction("Uncomment", action); //$NON-NLS-1$
1520 markAsStateDependentAction("Uncomment", true); //$NON-NLS-1$
1521 // WorkbenchHelp.setHelp(action, IJavaHelpContextIds.UNCOMMENT_ACTION);
1523 action = new ToggleCommentAction(PHPEditorMessages.getResourceBundle(),
1524 "ToggleComment.", this); //$NON-NLS-1$
1525 action.setActionDefinitionId(PHPEditorActionDefinitionIds.TOGGLE_COMMENT);
1526 setAction("ToggleComment", action); //$NON-NLS-1$
1527 markAsStateDependentAction("ToggleComment", true); //$NON-NLS-1$
1528 //WorkbenchHelp.setHelp(action,
1529 // IJavaHelpContextIds.TOGGLE_COMMENT_ACTION);
1530 configureToggleCommentAction();
1532 action = new TextOperationAction(PHPEditorMessages.getResourceBundle(),
1533 "Format.", this, ISourceViewer.FORMAT); //$NON-NLS-1$
1534 action.setActionDefinitionId(PHPEditorActionDefinitionIds.FORMAT);
1535 setAction("Format", action); //$NON-NLS-1$
1536 markAsStateDependentAction("Format", true); //$NON-NLS-1$
1537 markAsSelectionDependentAction("Format", true); //$NON-NLS-1$
1538 // WorkbenchHelp.setHelp(action, IJavaHelpContextIds.FORMAT_ACTION);
1540 // action = new AddBlockCommentAction(PHPEditorMessages.getResourceBundle(),
1541 // "AddBlockComment.", this); //$NON-NLS-1$
1543 // .setActionDefinitionId(PHPEditorActionDefinitionIds.ADD_BLOCK_COMMENT);
1544 // setAction("AddBlockComment", action); //$NON-NLS-1$
1545 // markAsStateDependentAction("AddBlockComment", true); //$NON-NLS-1$
1546 // markAsSelectionDependentAction("AddBlockComment", true); //$NON-NLS-1$
1547 // // WorkbenchHelp.setHelp(action,
1548 // // IJavaHelpContextIds.ADD_BLOCK_COMMENT_ACTION);
1549 // action = new RemoveBlockCommentAction(
1550 // PHPEditorMessages.getResourceBundle(), "RemoveBlockComment.", this); //$NON-NLS-1$
1552 // .setActionDefinitionId(PHPEditorActionDefinitionIds.REMOVE_BLOCK_COMMENT);
1553 // setAction("RemoveBlockComment", action); //$NON-NLS-1$
1554 // markAsStateDependentAction("RemoveBlockComment", true); //$NON-NLS-1$
1555 // markAsSelectionDependentAction("RemoveBlockComment", true); //$NON-NLS-1$
1556 // WorkbenchHelp.setHelp(action,
1557 // IJavaHelpContextIds.ADD_BLOCK_COMMENT_ACTION);
1558 // action= new IndentAction(PHPEditorMessages.getResourceBundle(),
1559 // "Indent.", this, false); //$NON-NLS-1$
1560 // action.setActionDefinitionId(PHPEditorActionDefinitionIds.INDENT);
1561 // setAction("Indent", action); //$NON-NLS-1$
1562 // markAsStateDependentAction("Indent", true); //$NON-NLS-1$
1563 // markAsSelectionDependentAction("Indent", true); //$NON-NLS-1$
1564 //// WorkbenchHelp.setHelp(action, IJavaHelpContextIds.INDENT_ACTION);
1566 // action= new IndentAction(PHPEditorMessages.getResourceBundle(),
1567 // "Indent.", this, true); //$NON-NLS-1$
1568 // setAction("IndentOnTab", action); //$NON-NLS-1$
1569 // markAsStateDependentAction("IndentOnTab", true); //$NON-NLS-1$
1570 // markAsSelectionDependentAction("IndentOnTab", true); //$NON-NLS-1$
1572 if (getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_SMART_TAB)) {
1573 // don't replace Shift Right - have to make sure their enablement is
1574 // mutually exclusive
1575 // removeActionActivationCode(ITextEditorActionConstants.SHIFT_RIGHT);
1576 setActionActivationCode("IndentOnTab", '\t', -1, SWT.NONE); //$NON-NLS-1$
1578 fGenerateActionGroup = new GenerateActionGroup(this,
1579 ITextEditorActionConstants.GROUP_EDIT);
1580 fActionGroups = new CompositeActionGroup(
1581 new ActionGroup[] { fGenerateActionGroup });
1582 // We have to keep the context menu group separate to have better
1585 fContextMenuGroup = new CompositeActionGroup(
1586 new ActionGroup[] { fGenerateActionGroup });
1588 // new LocalHistoryActionGroup(this,
1589 // ITextEditorActionConstants.GROUP_EDIT)});
1594 * @see JavaEditor#getElementAt(int)
1596 protected IJavaElement getElementAt(int offset) {
1597 return getElementAt(offset, true);
1601 * Returns the most narrow element including the given offset. If
1602 * <code>reconcile</code> is <code>true</code> the editor's input element
1603 * is reconciled in advance. If it is <code>false</code> this method only
1604 * returns a result if the editor's input element does not need to be
1608 * the offset included by the retrieved element
1610 * <code>true</code> if working copy should be reconciled
1612 protected IJavaElement getElementAt(int offset, boolean reconcile) {
1613 IWorkingCopyManager manager = PHPeclipsePlugin.getDefault()
1614 .getWorkingCopyManager();
1615 ICompilationUnit unit = manager.getWorkingCopy(getEditorInput());
1619 synchronized (unit) {
1622 return unit.getElementAt(offset);
1623 } else if (unit.isConsistent())
1624 return unit.getElementAt(offset);
1625 } catch (JavaModelException x) {
1626 PHPeclipsePlugin.log(x.getStatus());
1627 // nothing found, be tolerant and go on
1634 * @see JavaEditor#getCorrespondingElement(IJavaElement)
1636 protected IJavaElement getCorrespondingElement(IJavaElement element) {
1638 return EditorUtility.getWorkingCopy(element, true);
1639 } catch (JavaModelException x) {
1640 PHPeclipsePlugin.log(x.getStatus());
1641 // nothing found, be tolerant and go on
1646 public void createPartControl(Composite parent) {
1647 super.createPartControl(parent);
1648 // fPaintManager = new PaintManager(getSourceViewer());
1649 LinePainter linePainter;
1650 linePainter = new LinePainter(getSourceViewer());
1652 .setHighlightColor(new Color(Display.getCurrent(), 225, 235, 224));
1653 // fPaintManager.addPainter(linePainter);
1654 if (isBracketHighlightingEnabled())
1655 startBracketHighlighting();
1656 if (isLineHighlightingEnabled())
1657 startLineHighlighting();
1658 if (isPrintMarginVisible())
1660 // Iterator e = ANNOTATION_MAP.keySet().iterator();
1661 // while (e.hasNext()) {
1662 // AnnotationType type = (AnnotationType) e.next();
1663 // if (isAnnotationIndicationEnabled(type))
1664 // startAnnotationIndication(type);
1666 if (isTabConversionEnabled())
1667 startTabConversion();
1668 // if (isOverviewRulerVisible())
1669 // showOverviewRuler();
1671 // Preferences preferences =
1672 // PHPeclipsePlugin.getDefault().getPluginPreferences();
1673 // preferences.addPropertyChangeListener(fPropertyChangeListener);
1674 IPreferenceStore preferenceStore = getPreferenceStore();
1675 boolean closeBracketsPHP = preferenceStore.getBoolean(CLOSE_BRACKETS_PHP);
1676 boolean closeStringsPHP = preferenceStore.getBoolean(CLOSE_STRINGS_PHP);
1677 boolean closeBracketsHTML = preferenceStore.getBoolean(CLOSE_BRACKETS_HTML);
1678 boolean closeStringsHTML = preferenceStore.getBoolean(CLOSE_STRINGS_HTML);
1679 fBracketInserter.setCloseBracketsPHPEnabled(closeBracketsPHP);
1680 fBracketInserter.setCloseStringsPHPEnabled(closeStringsPHP);
1681 fBracketInserter.setCloseBracketsHTMLEnabled(closeBracketsHTML);
1682 fBracketInserter.setCloseStringsHTMLEnabled(closeStringsHTML);
1683 ISourceViewer sourceViewer = getSourceViewer();
1684 if (sourceViewer instanceof ITextViewerExtension)
1685 ((ITextViewerExtension) sourceViewer)
1686 .prependVerifyKeyListener(fBracketInserter);
1689 private static char getPeerCharacter(char character) {
1690 switch (character) {
1702 throw new IllegalArgumentException();
1706 private void startBracketHighlighting() {
1707 if (fBracketPainter == null) {
1708 ISourceViewer sourceViewer = getSourceViewer();
1709 fBracketPainter = new BracketPainter(sourceViewer);
1710 fBracketPainter.setHighlightColor(getColor(MATCHING_BRACKETS_COLOR));
1711 // fPaintManager.addPainter(fBracketPainter);
1715 private void stopBracketHighlighting() {
1716 if (fBracketPainter != null) {
1717 // fPaintManager.removePainter(fBracketPainter);
1718 fBracketPainter.deactivate(true);
1719 fBracketPainter.dispose();
1720 fBracketPainter = null;
1724 private boolean isBracketHighlightingEnabled() {
1725 IPreferenceStore store = getPreferenceStore();
1726 return store.getBoolean(MATCHING_BRACKETS);
1729 private void startLineHighlighting() {
1730 if (fLinePainter == null) {
1731 ISourceViewer sourceViewer = getSourceViewer();
1732 fLinePainter = new LinePainter(sourceViewer);
1733 fLinePainter.setHighlightColor(getColor(CURRENT_LINE_COLOR));
1734 // fPaintManager.addPainter(fLinePainter);
1738 private void stopLineHighlighting() {
1739 if (fLinePainter != null) {
1740 // fPaintManager.removePainter(fLinePainter);
1741 fLinePainter.deactivate(true);
1742 fLinePainter.dispose();
1743 fLinePainter = null;
1747 private boolean isLineHighlightingEnabled() {
1748 IPreferenceStore store = getPreferenceStore();
1749 return store.getBoolean(CURRENT_LINE);
1752 private void showPrintMargin() {
1753 if (fPrintMarginPainter == null) {
1754 fPrintMarginPainter = new PrintMarginPainter(getSourceViewer());
1755 fPrintMarginPainter.setMarginRulerColor(getColor(PRINT_MARGIN_COLOR));
1756 fPrintMarginPainter.setMarginRulerColumn(getPreferenceStore().getInt(
1757 PRINT_MARGIN_COLUMN));
1758 // fPaintManager.addPainter(fPrintMarginPainter);
1762 private void hidePrintMargin() {
1763 if (fPrintMarginPainter != null) {
1764 // fPaintManager.removePainter(fPrintMarginPainter);
1765 fPrintMarginPainter.deactivate(true);
1766 fPrintMarginPainter.dispose();
1767 fPrintMarginPainter = null;
1771 private boolean isPrintMarginVisible() {
1772 IPreferenceStore store = getPreferenceStore();
1773 return store.getBoolean(PRINT_MARGIN);
1776 // private void startAnnotationIndication(AnnotationType annotationType) {
1777 // if (fProblemPainter == null) {
1778 // fProblemPainter = new ProblemPainter(this, getSourceViewer());
1779 //// fPaintManager.addPainter(fProblemPainter);
1781 // fProblemPainter.setColor(annotationType, getColor(annotationType));
1782 // fProblemPainter.paintAnnotations(annotationType, true);
1783 // fProblemPainter.paint(IPainter.CONFIGURATION);
1786 // private void shutdownAnnotationIndication() {
1787 // if (fProblemPainter != null) {
1789 // if (!fProblemPainter.isPaintingAnnotations()) {
1790 //// fPaintManager.removePainter(fProblemPainter);
1791 // fProblemPainter.deactivate(true);
1792 // fProblemPainter.dispose();
1793 // fProblemPainter = null;
1795 // fProblemPainter.paint(IPainter.CONFIGURATION);
1800 // private void stopAnnotationIndication(AnnotationType annotationType) {
1801 // if (fProblemPainter != null) {
1802 // fProblemPainter.paintAnnotations(annotationType, false);
1803 // shutdownAnnotationIndication();
1807 // private boolean isAnnotationIndicationEnabled(AnnotationType
1808 // annotationType) {
1809 // IPreferenceStore store = getPreferenceStore();
1810 // AnnotationInfo info = (AnnotationInfo)
1811 // ANNOTATION_MAP.get(annotationType);
1812 // if (info != null)
1813 // return store.getBoolean(info.fEditorPreference);
1818 // isAnnotationIndicationInOverviewRulerEnabled(AnnotationType
1819 // annotationType) {
1820 // IPreferenceStore store = getPreferenceStore();
1821 // AnnotationInfo info = (AnnotationInfo)
1822 // ANNOTATION_MAP.get(annotationType);
1823 // if (info != null)
1824 // return store.getBoolean(info.fOverviewRulerPreference);
1828 // private void showAnnotationIndicationInOverviewRuler(AnnotationType
1829 // annotationType, boolean show) {
1830 // AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
1831 // OverviewRuler ruler = asv.getOverviewRuler();
1832 // if (ruler != null) {
1833 // ruler.setColor(annotationType, getColor(annotationType));
1834 // ruler.showAnnotation(annotationType, show);
1839 // private void setColorInOverviewRuler(AnnotationType annotationType, Color
1841 // AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
1842 // OverviewRuler ruler = asv.getOverviewRuler();
1843 // if (ruler != null) {
1844 // ruler.setColor(annotationType, color);
1849 private int getTabSize() {
1850 Preferences preferences = PHPeclipsePlugin.getDefault()
1851 .getPluginPreferences();
1852 return preferences.getInt(CODE_FORMATTER_TAB_SIZE);
1855 private boolean isTabConversionEnabled() {
1856 IPreferenceStore store = getPreferenceStore();
1857 return store.getBoolean(SPACES_FOR_TABS);
1860 // private void showOverviewRuler() {
1861 // AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
1862 // asv.showOverviewRuler();
1864 // OverviewRuler overviewRuler = asv.getOverviewRuler();
1865 // if (overviewRuler != null) {
1866 // for (int i = 0; i < ANNOTATION_LAYERS.length; i++) {
1867 // AnnotationType type = ANNOTATION_LAYERS[i];
1868 // overviewRuler.setLayer(type, i);
1869 // if (isAnnotationIndicationInOverviewRulerEnabled(type))
1870 // showAnnotationIndicationInOverviewRuler(type, true);
1875 // private void hideOverviewRuler() {
1876 // AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
1877 // asv.hideOverviewRuler();
1880 // private boolean isOverviewRulerVisible() {
1881 // IPreferenceStore store = getPreferenceStore();
1882 // return store.getBoolean(OVERVIEW_RULER);
1884 private Color getColor(String key) {
1885 RGB rgb = PreferenceConverter.getColor(getPreferenceStore(), key);
1886 return getColor(rgb);
1889 private Color getColor(RGB rgb) {
1890 JavaTextTools textTools = PHPeclipsePlugin.getDefault().getJavaTextTools();
1891 return textTools.getColorManager().getColor(rgb);
1894 // private Color getColor(AnnotationType annotationType) {
1895 // AnnotationInfo info = (AnnotationInfo)
1896 // ANNOTATION_MAP.get(annotationType);
1897 // if (info != null)
1898 // return getColor(info.fColorPreference);
1901 public void dispose() {
1902 ISourceViewer sourceViewer = getSourceViewer();
1903 if (sourceViewer instanceof ITextViewerExtension)
1904 ((ITextViewerExtension) sourceViewer)
1905 .removeVerifyKeyListener(fBracketInserter);
1906 // if (fPropertyChangeListener != null) {
1907 // Preferences preferences =
1908 // PHPeclipsePlugin.getDefault().getPluginPreferences();
1909 // preferences.removePropertyChangeListener(fPropertyChangeListener);
1910 // fPropertyChangeListener = null;
1912 if (fJavaEditorErrorTickUpdater != null) {
1913 fJavaEditorErrorTickUpdater.dispose();
1914 fJavaEditorErrorTickUpdater = null;
1916 // if (fSelectionHistory != null)
1917 // fSelectionHistory.dispose();
1918 // if (fPaintManager != null) {
1919 // fPaintManager.dispose();
1920 // fPaintManager = null;
1922 if (fActionGroups != null) {
1923 fActionGroups.dispose();
1924 fActionGroups = null;
1929 // protected AnnotationType getAnnotationType(String preferenceKey) {
1930 // Iterator e = ANNOTATION_MAP.keySet().iterator();
1931 // while (e.hasNext()) {
1932 // AnnotationType type = (AnnotationType) e.next();
1933 // AnnotationInfo info = (AnnotationInfo) ANNOTATION_MAP.get(type);
1934 // if (info != null) {
1935 // if (preferenceKey.equals(info.fColorPreference)
1936 // || preferenceKey.equals(info.fEditorPreference)
1937 // || preferenceKey.equals(info.fOverviewRulerPreference))
1944 * @see AbstractTextEditor#handlePreferenceStoreChanged(PropertyChangeEvent)
1946 protected void handlePreferenceStoreChanged(PropertyChangeEvent event) {
1948 AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
1950 String p = event.getProperty();
1951 if (CLOSE_BRACKETS_PHP.equals(p)) {
1952 fBracketInserter.setCloseBracketsPHPEnabled(getPreferenceStore()
1956 if (CLOSE_STRINGS_PHP.equals(p)) {
1957 fBracketInserter.setCloseStringsPHPEnabled(getPreferenceStore()
1961 if (CLOSE_BRACKETS_HTML.equals(p)) {
1962 fBracketInserter.setCloseBracketsHTMLEnabled(getPreferenceStore()
1966 if (CLOSE_STRINGS_HTML.equals(p)) {
1967 fBracketInserter.setCloseStringsHTMLEnabled(getPreferenceStore()
1971 if (SPACES_FOR_TABS.equals(p)) {
1972 if (isTabConversionEnabled())
1973 startTabConversion();
1975 stopTabConversion();
1978 if (MATCHING_BRACKETS.equals(p)) {
1979 if (isBracketHighlightingEnabled())
1980 startBracketHighlighting();
1982 stopBracketHighlighting();
1985 if (MATCHING_BRACKETS_COLOR.equals(p)) {
1986 if (fBracketPainter != null)
1988 .setHighlightColor(getColor(MATCHING_BRACKETS_COLOR));
1991 if (CURRENT_LINE.equals(p)) {
1992 if (isLineHighlightingEnabled())
1993 startLineHighlighting();
1995 stopLineHighlighting();
1998 if (CURRENT_LINE_COLOR.equals(p)) {
1999 if (fLinePainter != null) {
2000 stopLineHighlighting();
2001 startLineHighlighting();
2005 if (PRINT_MARGIN.equals(p)) {
2006 if (isPrintMarginVisible())
2012 if (PRINT_MARGIN_COLOR.equals(p)) {
2013 if (fPrintMarginPainter != null)
2015 .setMarginRulerColor(getColor(PRINT_MARGIN_COLOR));
2018 if (PRINT_MARGIN_COLUMN.equals(p)) {
2019 if (fPrintMarginPainter != null)
2020 fPrintMarginPainter.setMarginRulerColumn(getPreferenceStore()
2021 .getInt(PRINT_MARGIN_COLUMN));
2024 // if (OVERVIEW_RULER.equals(p)) {
2025 // if (isOverviewRulerVisible())
2026 // showOverviewRuler();
2028 // hideOverviewRuler();
2031 // AnnotationType type = getAnnotationType(p);
2032 // if (type != null) {
2034 // AnnotationInfo info = (AnnotationInfo)
2035 // ANNOTATION_MAP.get(type);
2036 // if (info.fColorPreference.equals(p)) {
2037 // Color color = getColor(type);
2038 // if (fProblemPainter != null) {
2039 // fProblemPainter.setColor(type, color);
2040 // fProblemPainter.paint(IPainter.CONFIGURATION);
2042 // setColorInOverviewRuler(type, color);
2046 // if (info.fEditorPreference.equals(p)) {
2047 // if (isAnnotationIndicationEnabled(type))
2048 // startAnnotationIndication(type);
2050 // stopAnnotationIndication(type);
2054 // if (info.fOverviewRulerPreference.equals(p)) {
2055 // if (isAnnotationIndicationInOverviewRulerEnabled(type))
2056 // showAnnotationIndicationInOverviewRuler(type, true);
2058 // showAnnotationIndicationInOverviewRuler(type, false);
2062 IContentAssistant c = asv.getContentAssistant();
2063 if (c instanceof ContentAssistant)
2064 ContentAssistPreference.changeConfiguration((ContentAssistant) c,
2065 getPreferenceStore(), event);
2068 super.handlePreferenceStoreChanged(event);
2073 * @see org.eclipse.jdt.internal.ui.javaeditor.JavaEditor#handlePreferencePropertyChanged(org.eclipse.core.runtime.Preferences.PropertyChangeEvent)
2075 protected void handlePreferencePropertyChanged(
2076 org.eclipse.core.runtime.Preferences.PropertyChangeEvent event) {
2077 AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
2079 String p = event.getProperty();
2080 if (CODE_FORMATTER_TAB_SIZE.equals(p)) {
2081 asv.updateIndentationPrefixes();
2082 if (fTabConverter != null)
2083 fTabConverter.setNumberOfSpacesPerTab(getTabSize());
2086 super.handlePreferencePropertyChanged(event);
2090 * Handles a property change event describing a change of the php core's
2091 * preferences and updates the preference related editor properties.
2094 * the property change event
2097 // handlePreferencePropertyChanged(org.eclipse.core.runtime.Preferences.PropertyChangeEvent
2099 // AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
2100 // if (asv != null) {
2101 // String p = event.getProperty();
2102 // if (CODE_FORMATTER_TAB_SIZE.equals(p)) {
2103 // asv.updateIndentationPrefixes();
2104 // if (fTabConverter != null)
2105 // fTabConverter.setNumberOfSpacesPerTab(getTabSize());
2110 * @see org.eclipse.jdt.internal.ui.javaeditor.JavaEditor#createJavaSourceViewer(org.eclipse.swt.widgets.Composite,
2111 * org.eclipse.jface.text.source.IVerticalRuler,
2112 * org.eclipse.jface.text.source.IOverviewRuler, boolean, int)
2114 protected ISourceViewer createJavaSourceViewer(Composite parent,
2115 IVerticalRuler verticalRuler, IOverviewRuler overviewRuler,
2116 boolean isOverviewRulerVisible, int styles, IPreferenceStore store) {
2117 return new AdaptedSourceViewer(parent, verticalRuler, overviewRuler,
2118 isOverviewRulerVisible, styles, store);
2121 // protected ISourceViewer createJavaSourceViewer(Composite parent,
2122 // IVerticalRuler ruler, int styles) {
2123 // return new AdaptedSourceViewer(parent, ruler, styles);
2125 private boolean isValidSelection(int offset, int length) {
2126 IDocumentProvider provider = getDocumentProvider();
2127 if (provider != null) {
2128 IDocument document = provider.getDocument(getEditorInput());
2129 if (document != null) {
2130 int end = offset + length;
2131 int documentLength = document.getLength();
2132 return 0 <= offset && offset <= documentLength && 0 <= end
2133 && end <= documentLength;
2140 * @see org.eclipse.jdt.internal.ui.javaeditor.JavaEditor#getInputElement()
2142 protected IJavaElement getInputJavaElement() {
2143 return PHPeclipsePlugin.getDefault().getWorkingCopyManager().getWorkingCopy(getEditorInput());
2146 * @see AbstractTextEditor#editorContextMenuAboutToShow(IMenuManager)
2148 public void editorContextMenuAboutToShow(IMenuManager menu) {
2149 super.editorContextMenuAboutToShow(menu);
2150 ActionContext context = new ActionContext(getSelectionProvider()
2152 fContextMenuGroup.setContext(context);
2153 fContextMenuGroup.fillContextMenu(menu);
2154 fContextMenuGroup.setContext(null);
2158 * @see JavaEditor#setOutlinePageInput(JavaOutlinePage, IEditorInput)
2160 protected void setOutlinePageInput(JavaOutlinePage page, IEditorInput input) {
2162 IWorkingCopyManager manager = PHPeclipsePlugin.getDefault()
2163 .getWorkingCopyManager();
2164 page.setInput(manager.getWorkingCopy(input));
2170 * @see AbstractTextEditor#performSaveOperation(WorkspaceModifyOperation,
2173 // protected void performSaveOperation(WorkspaceModifyOperation operation,
2174 // IProgressMonitor progressMonitor) {
2175 // IDocumentProvider p = getDocumentProvider();
2176 // if (p instanceof PHPDocumentProvider) {
2177 // PHPDocumentProvider cp = (PHPDocumentProvider) p;
2178 // cp.setSavePolicy(fSavePolicy);
2182 // super.performSaveOperation(operation, progressMonitor);
2184 // if (p instanceof PHPDocumentProvider) {
2185 // PHPDocumentProvider cp = (PHPDocumentProvider) p;
2186 // cp.setSavePolicy(null);
2191 * @see AbstractTextEditor#doSave(IProgressMonitor)
2193 public void doSave(IProgressMonitor progressMonitor) {
2195 IDocumentProvider p = getDocumentProvider();
2197 // editor has been closed
2201 if (p.isDeleted(getEditorInput())) {
2203 if (isSaveAsAllowed()) {
2206 * 1GEUSSR: ITPUI:ALL - User should never loose changes made in the
2207 * editors. Changed Behavior to make sure that if called inside a
2208 * regular save (because of deletion of input element) there is a way to
2209 * report back to the caller.
2211 performSaveAs(progressMonitor);
2216 * 1GF5YOX: ITPJUI:ALL - Save of delete file claims it's still there
2217 * Missing resources.
2219 Shell shell = getSite().getShell();
2224 .getString("PHPUnitEditor.error.saving.title1"), PHPEditorMessages.getString("PHPUnitEditor.error.saving.message1")); //$NON-NLS-1$ //$NON-NLS-2$
2229 setStatusLineErrorMessage(null);
2231 updateState(getEditorInput());
2232 validateState(getEditorInput());
2234 IWorkingCopyManager manager = PHPeclipsePlugin.getDefault()
2235 .getWorkingCopyManager();
2236 ICompilationUnit unit = manager.getWorkingCopy(getEditorInput());
2239 synchronized (unit) {
2240 performSave(false, progressMonitor);
2243 performSave(false, progressMonitor);
2247 public boolean isSaveAsAllowed() {
2252 * The compilation unit editor implementation of this
2253 * <code>AbstractTextEditor</code> method asks the user for the workspace
2254 * path of a file resource and saves the document there. See
2255 * http://dev.eclipse.org/bugs/show_bug.cgi?id=6295
2257 * @param progressMonitor
2258 * the progress monitor
2260 protected void performSaveAs(IProgressMonitor progressMonitor) {
2262 Shell shell = getSite().getShell();
2263 IEditorInput input = getEditorInput();
2265 SaveAsDialog dialog = new SaveAsDialog(shell);
2267 IFile original = (input instanceof IFileEditorInput) ? ((IFileEditorInput) input)
2270 if (original != null)
2271 dialog.setOriginalFile(original);
2275 IDocumentProvider provider = getDocumentProvider();
2276 if (provider == null) {
2277 // editor has been programmatically closed while the dialog was open
2281 if (provider.isDeleted(input) && original != null) {
2282 String message = PHPEditorMessages
2283 .getFormattedString(
2284 "CompilationUnitEditor.warning.save.delete", new Object[] { original.getName() }); //$NON-NLS-1$
2285 dialog.setErrorMessage(null);
2286 dialog.setMessage(message, IMessageProvider.WARNING);
2289 if (dialog.open() == Window.CANCEL) {
2290 if (progressMonitor != null)
2291 progressMonitor.setCanceled(true);
2295 IPath filePath = dialog.getResult();
2296 if (filePath == null) {
2297 if (progressMonitor != null)
2298 progressMonitor.setCanceled(true);
2302 IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
2303 IFile file = workspaceRoot.getFile(filePath);
2304 final IEditorInput newInput = new FileEditorInput(file);
2306 boolean success = false;
2309 provider.aboutToChange(newInput);
2310 getDocumentProvider().saveDocument(progressMonitor, newInput,
2311 getDocumentProvider().getDocument(getEditorInput()), true);
2314 } catch (CoreException x) {
2315 IStatus status = x.getStatus();
2316 if (status == null || status.getSeverity() != IStatus.CANCEL)
2321 .getString("CompilationUnitEditor.error.saving.title2"), PHPEditorMessages.getString("CompilationUnitEditor.error.saving.message2"), x.getStatus()); //$NON-NLS-1$ //$NON-NLS-2$
2323 provider.changed(newInput);
2328 if (progressMonitor != null)
2329 progressMonitor.setCanceled(!success);
2333 * @see AbstractTextEditor#doSetInput(IEditorInput)
2335 protected void doSetInput(IEditorInput input) throws CoreException {
2336 super.doSetInput(input);
2337 configureTabConverter();
2338 configureToggleCommentAction();
2343 // org.eclipse.jdt.internal.ui.javaeditor.JavaEditor#installOverrideIndicator(boolean)
2346 // protected void installOverrideIndicator(boolean waitForReconcilation) {
2347 // IAnnotationModel model=
2348 // getDocumentProvider().getAnnotationModel(getEditorInput());
2349 // if (!waitForReconcilation)
2350 // super.installOverrideIndicator(false);
2352 // uninstallOverrideIndicator();
2353 // IJavaElement inputElement= getInputJavaElement();
2354 // if (model == null || inputElement == null)
2357 // fOverrideIndicatorManager= new OverrideIndicatorManager(model,
2358 // inputElement, null);
2359 // addReconcileListener(fOverrideIndicatorManager);
2365 // org.eclipse.jdt.internal.ui.javaeditor.JavaEditor#uninstallOverrideIndicator()
2368 // protected void uninstallOverrideIndicator() {
2369 // if (fOverrideIndicatorManager != null)
2370 // removeReconcileListener(fOverrideIndicatorManager);
2371 // super.uninstallOverrideIndicator();
2375 * Configures the toggle comment action
2379 private void configureToggleCommentAction() {
2380 IAction action = getAction("ToggleComment"); //$NON-NLS-1$
2381 if (action instanceof ToggleCommentAction) {
2382 ISourceViewer sourceViewer = getSourceViewer();
2383 SourceViewerConfiguration configuration = getSourceViewerConfiguration();
2384 ((ToggleCommentAction) action).configure(sourceViewer, configuration);
2388 private void configureTabConverter() {
2389 if (fTabConverter != null) {
2390 IDocumentProvider provider = getDocumentProvider();
2391 if (provider instanceof PHPDocumentProvider) {
2392 PHPDocumentProvider cup = (PHPDocumentProvider) provider;
2393 fTabConverter.setLineTracker(cup.createLineTracker(getEditorInput()));
2398 private void startTabConversion() {
2399 if (fTabConverter == null) {
2400 fTabConverter = new TabConverter();
2401 configureTabConverter();
2402 fTabConverter.setNumberOfSpacesPerTab(getTabSize());
2403 AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
2404 asv.addTextConverter(fTabConverter);
2405 // http://dev.eclipse.org/bugs/show_bug.cgi?id=19270
2406 asv.updateIndentationPrefixes();
2410 private void stopTabConversion() {
2411 if (fTabConverter != null) {
2412 AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
2413 asv.removeTextConverter(fTabConverter);
2414 // http://dev.eclipse.org/bugs/show_bug.cgi?id=19270
2415 asv.updateIndentationPrefixes();
2416 fTabConverter = null;
2421 * @see org.eclipse.ui.texteditor.AbstractTextEditor#performSave(boolean,
2422 * org.eclipse.core.runtime.IProgressMonitor)
2424 protected void performSave(boolean overwrite, IProgressMonitor progressMonitor) {
2425 IDocumentProvider p = getDocumentProvider();
2426 if (p instanceof PHPDocumentProvider) {
2427 PHPDocumentProvider cp = (PHPDocumentProvider) p;
2428 cp.setSavePolicy(fSavePolicy);
2431 super.performSave(overwrite, progressMonitor);
2433 if (p instanceof PHPDocumentProvider) {
2434 PHPDocumentProvider cp = (PHPDocumentProvider) p;
2435 cp.setSavePolicy(null);
2441 * @see AbstractTextEditor#doSaveAs
2443 public void doSaveAs() {
2444 if (askIfNonWorkbenchEncodingIsOk()) {
2450 * Asks the user if it is ok to store in non-workbench encoding.
2452 * @return <true>if the user wants to continue
2454 private boolean askIfNonWorkbenchEncodingIsOk() {
2455 IDocumentProvider provider = getDocumentProvider();
2456 if (provider instanceof IStorageDocumentProvider) {
2457 IEditorInput input = getEditorInput();
2458 IStorageDocumentProvider storageProvider = (IStorageDocumentProvider) provider;
2459 String encoding = storageProvider.getEncoding(input);
2460 String defaultEncoding = storageProvider.getDefaultEncoding();
2461 if (encoding != null && !encoding.equals(defaultEncoding)) {
2462 Shell shell = getSite().getShell();
2463 String title = PHPEditorMessages
2464 .getString("PHPUnitEditor.warning.save.nonWorkbenchEncoding.title"); //$NON-NLS-1$
2470 .getString("PHPUnitEditor.warning.save.nonWorkbenchEncoding.message1"),
2471 new String[] { input.getName(), encoding }); //$NON-NLS-1$
2476 .getString("PHPUnitEditor.warning.save.nonWorkbenchEncoding.message2"),
2477 new String[] { encoding }); //$NON-NLS-1$
2478 return MessageDialog.openQuestion(shell, title, msg);
2485 * @see org.eclipse.jdt.internal.ui.text.java.IJavaReconcilingListener#aboutToBeReconciled()
2488 public void aboutToBeReconciled() {
2490 // Notify AST provider
2491 // PHPeclipsePlugin.getDefault().getASTProvider().aboutToBeReconciled(getInputJavaElement());
2494 Object[] listeners = fReconcilingListeners.getListeners();
2495 for (int i = 0, length= listeners.length; i < length; ++i)
2496 ((IJavaReconcilingListener)listeners[i]).aboutToBeReconciled();
2500 * @see org.eclipse.jdt.internal.ui.text.java.IJavaReconcilingListener#reconciled(CompilationUnit, boolean, IProgressMonitor)
2503 public void reconciled(CompilationUnit ast, boolean forced, IProgressMonitor progressMonitor) {
2505 // Always notify AST provider
2506 // PHPeclipsePlugin.getDefault().getASTProvider().reconciled(ast, getInputJavaElement());
2509 // Object[] listeners = fReconcilingListeners.getListeners();
2510 // for (int i = 0, length= listeners.length; i < length; ++i)
2511 // ((IJavaReconcilingListener)listeners[i]).reconciled(ast, forced, progressMonitor);
2513 // Update Java Outline page selection
2514 if (!forced && !progressMonitor.isCanceled()) {
2515 Shell shell= getSite().getShell();
2516 if (shell != null && !shell.isDisposed()) {
2517 shell.getDisplay().asyncExec(new Runnable() {
2526 private boolean synchronizeOutlineOnCursorMove() {
2527 return PreferenceConstants.getPreferenceStore().getBoolean(
2528 PreferenceConstants.EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE);
2532 * Returns the updated java element for the old java element.
2534 private IJavaElement findElement(IJavaElement element) {
2535 if (element == null)
2537 IWorkingCopyManager manager = PHPeclipsePlugin.getDefault()
2538 .getWorkingCopyManager();
2539 ICompilationUnit unit = manager.getWorkingCopy(getEditorInput());
2542 synchronized (unit) {
2545 IJavaElement[] findings = unit.findElements(element);
2546 if (findings != null && findings.length > 0)
2548 } catch (JavaModelException x) {
2549 PHPeclipsePlugin.log(x.getStatus());
2550 // nothing found, be tolerant and go on
2557 * Returns the offset of the given Java element.
2559 private int getOffset(IJavaElement element) {
2560 if (element instanceof ISourceReference) {
2561 ISourceReference sr = (ISourceReference) element;
2563 ISourceRange srcRange = sr.getSourceRange();
2564 if (srcRange != null)
2565 return srcRange.getOffset();
2566 } catch (JavaModelException e) {
2575 * @see AbstractTextEditor#restoreSelection()
2577 // protected void restoreSelection() {
2579 // if (getSourceViewer() == null || fRememberedSelection == null)
2581 // IJavaElement newElement = findElement(fRememberedElement);
2582 // int newOffset = getOffset(newElement);
2583 // int delta = (newOffset > -1 && fRememberedElementOffset > -1) ? newOffset
2584 // - fRememberedElementOffset : 0;
2585 // if (isValidSelection(delta + fRememberedSelection.getOffset(),
2586 // fRememberedSelection.getLength()))
2587 // selectAndReveal(delta + fRememberedSelection.getOffset(),
2588 // fRememberedSelection.getLength());
2590 // fRememberedSelection = null;
2591 // fRememberedElement = null;
2592 // fRememberedElementOffset = -1;
2597 * Tells whether this is the active editor in the active page.
2599 * @return <code>true</code> if this is the active editor in the active page
2600 * @see IWorkbenchPage#getActiveEditor();
2602 protected final boolean isActiveEditor() {
2603 IWorkbenchWindow window= getSite().getWorkbenchWindow();
2604 IWorkbenchPage page= window.getActivePage();
2607 IEditorPart activeEditor= page.getActiveEditor();
2608 return activeEditor != null && activeEditor.equals(this);
2612 * Adds the given listener.
2613 * Has no effect if an identical listener was not already registered.
2615 * @param listener The reconcile listener to be added
2618 final void addReconcileListener(IJavaReconcilingListener listener) {
2619 synchronized (fReconcilingListeners) {
2620 fReconcilingListeners.add(listener);
2625 * Removes the given listener.
2626 * Has no effect if an identical listener was not already registered.
2628 * @param listener the reconcile listener to be removed
2631 final void removeReconcileListener(IJavaReconcilingListener listener) {
2632 synchronized (fReconcilingListeners) {
2633 fReconcilingListeners.remove(listener);
2637 protected void updateStateDependentActions() {
2638 super.updateStateDependentActions();
2639 fGenerateActionGroup.editorStateChanged();
2643 * @see AbstractTextEditor#rememberSelection()
2645 protected void rememberSelection() {
2646 fRememberedSelection.remember();
2650 * @see AbstractTextEditor#restoreSelection()
2652 protected void restoreSelection() {
2653 fRememberedSelection.restore();
2657 * @see AbstractTextEditor#canHandleMove(IEditorInput, IEditorInput)
2659 protected boolean canHandleMove(IEditorInput originalElement, IEditorInput movedElement) {
2661 String oldExtension= ""; //$NON-NLS-1$
2662 if (originalElement instanceof IFileEditorInput) {
2663 IFile file= ((IFileEditorInput) originalElement).getFile();
2665 String ext= file.getFileExtension();
2671 String newExtension= ""; //$NON-NLS-1$
2672 if (movedElement instanceof IFileEditorInput) {
2673 IFile file= ((IFileEditorInput) movedElement).getFile();
2675 newExtension= file.getFileExtension();
2678 return oldExtension.equals(newExtension);
2682 * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#isPrefQuickDiffAlwaysOn()
2684 protected boolean isPrefQuickDiffAlwaysOn() {
2685 // reestablishes the behaviour from AbstractDecoratedTextEditor which was hacked by JavaEditor
2686 // to disable the change bar for the class file (attached source) java editor.
2687 IPreferenceStore store= getPreferenceStore();
2688 return store.getBoolean(AbstractDecoratedTextEditorPreferenceConstants.QUICK_DIFF_ALWAYS_ON);
2692 * @see org.eclipse.jdt.internal.ui.javaeditor.JavaEditor#getAdapter(java.lang.Class)
2694 public Object getAdapter(Class required) {
2695 if (SmartBackspaceManager.class.equals(required)) {
2696 if (getSourceViewer() instanceof JavaSourceViewer) {
2697 return ((JavaSourceViewer) getSourceViewer()).getBackspaceManager();
2701 return super.getAdapter(required);
2704 * Returns the mutex for the reconciler. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=63898
2705 * for a description of the problem.
2707 * TODO remove once the underlying problem is solved.
2709 * @return the lock reconcilers may use to synchronize on
2711 public Object getReconcilerLock() {
2712 return fReconcilerLock;
2716 * @see org.eclipse.ui.texteditor.AbstractTextEditor#editorSaved()
2718 protected void editorSaved() {
2719 super.editorSaved();
2720 ShowExternalPreviewAction a = ShowExternalPreviewAction.getInstance();
2722 a.refresh(ShowExternalPreviewAction.PHP_TYPE);