1 package net.sourceforge.phpeclipse.phpeditor;
3 import java.util.ArrayList;
4 import java.util.HashMap;
5 import java.util.Iterator;
9 import net.sourceforge.phpdt.internal.ui.text.ContentAssistPreference;
10 import net.sourceforge.phpdt.internal.ui.text.PHPPairMatcher;
11 import net.sourceforge.phpdt.internal.ui.text.java.IReconcilingParticipant;
12 import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionManager;
13 import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionUI;
14 import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionUI.ExitFlags;
15 import net.sourceforge.phpdt.ui.PreferenceConstants;
16 import net.sourceforge.phpdt.ui.text.JavaTextTools;
17 import net.sourceforge.phpeclipse.PHPCore;
18 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
20 import org.eclipse.core.resources.IFile;
21 import org.eclipse.core.runtime.CoreException;
22 import org.eclipse.core.runtime.Preferences;
23 import org.eclipse.core.runtime.Preferences.IPropertyChangeListener;
24 import org.eclipse.jface.preference.IPreferenceStore;
25 import org.eclipse.jface.preference.PreferenceConverter;
26 import org.eclipse.jface.text.AbstractHoverInformationControlManager;
27 import org.eclipse.jface.text.BadLocationException;
28 import org.eclipse.jface.text.DocumentCommand;
29 import org.eclipse.jface.text.IDocument;
30 import org.eclipse.jface.text.ILineTracker;
31 import org.eclipse.jface.text.IRegion;
32 import org.eclipse.jface.text.ITextSelection;
33 import org.eclipse.jface.text.ITextViewerExtension;
34 import org.eclipse.jface.text.ITypedRegion;
35 import org.eclipse.jface.text.IWidgetTokenKeeper;
36 import org.eclipse.jface.text.contentassist.ContentAssistant;
37 import org.eclipse.jface.text.contentassist.IContentAssistant;
38 import org.eclipse.jface.text.source.IAnnotationModel;
39 import org.eclipse.jface.text.source.ISourceViewer;
40 import org.eclipse.jface.text.source.IVerticalRuler;
41 import org.eclipse.jface.text.source.SourceViewer;
42 import org.eclipse.jface.text.source.SourceViewerConfiguration;
43 import org.eclipse.jface.util.PropertyChangeEvent;
44 import org.eclipse.swt.SWT;
45 import org.eclipse.swt.custom.StyledText;
46 import org.eclipse.swt.custom.VerifyKeyListener;
47 import org.eclipse.swt.events.VerifyEvent;
48 import org.eclipse.swt.graphics.Color;
49 import org.eclipse.swt.graphics.Point;
50 import org.eclipse.swt.graphics.RGB;
51 import org.eclipse.swt.graphics.Rectangle;
52 import org.eclipse.swt.widgets.Composite;
53 import org.eclipse.swt.widgets.Control;
54 import org.eclipse.swt.widgets.Display;
55 import org.eclipse.swt.widgets.Layout;
56 import org.eclipse.ui.IEditorInput;
57 import org.eclipse.ui.IFileEditorInput;
58 import org.eclipse.ui.help.WorkbenchHelp;
59 import org.eclipse.ui.texteditor.IDocumentProvider;
61 /**********************************************************************
62 Copyright (c) 2000, 2002 IBM Corp. and others.
63 All rights reserved. This program and the accompanying materials
64 are made available under the terms of the Common Public License v1.0
65 which accompanies this distribution, and is available at
66 http://www.eclipse.org/legal/cpl-v10.html
69 IBM Corporation - Initial implementation
70 Klaus Hartlage - www.eclipseproject.de
71 **********************************************************************/
73 * PHP specific text editor.
75 public class PHPUnitEditor extends PHPEditor {
76 interface ITextConverter {
77 void customizeDocumentCommand(IDocument document, DocumentCommand command);
80 class AdaptedRulerLayout extends Layout {
83 protected AdaptedSourceViewer fAdaptedSourceViewer;
85 protected AdaptedRulerLayout(int gap, AdaptedSourceViewer asv) {
87 fAdaptedSourceViewer = asv;
90 protected Point computeSize(
95 Control[] children = composite.getChildren();
97 children[children.length
98 - 1].computeSize(SWT.DEFAULT, SWT.DEFAULT, flushCache);
99 if (fAdaptedSourceViewer.isVerticalRulerVisible())
100 s.x += fAdaptedSourceViewer.getVerticalRuler().getWidth() + fGap;
104 protected void layout(Composite composite, boolean flushCache) {
105 Rectangle clArea = composite.getClientArea();
106 if (fAdaptedSourceViewer.isVerticalRulerVisible()) {
108 StyledText textWidget = fAdaptedSourceViewer.getTextWidget();
109 Rectangle trim = textWidget.computeTrim(0, 0, 0, 0);
110 int scrollbarHeight = trim.height;
112 IVerticalRuler vr = fAdaptedSourceViewer.getVerticalRuler();
113 int vrWidth = vr.getWidth();
116 if (fAdaptedSourceViewer.isOverviewRulerVisible()) {
117 OverviewRuler or = fAdaptedSourceViewer.getOverviewRuler();
118 orWidth = or.getWidth();
119 or.getControl().setBounds(
120 clArea.width - orWidth,
123 clArea.height - 3 * scrollbarHeight);
126 textWidget.setBounds(
129 clArea.width - vrWidth - orWidth - 2 * fGap,
131 vr.getControl().setBounds(
135 clArea.height - scrollbarHeight);
138 StyledText textWidget = fAdaptedSourceViewer.getTextWidget();
139 textWidget.setBounds(0, 0, clArea.width, clArea.height);
144 class AdaptedSourceViewer
145 extends SourceViewer { // extends JavaCorrectionSourceViewer {
147 private List fTextConverters;
149 private OverviewRuler fOverviewRuler;
150 private boolean fIsOverviewRulerVisible;
151 /** The viewer's overview ruler hovering controller */
152 private AbstractHoverInformationControlManager fOverviewRulerHoveringController;
154 private boolean fIgnoreTextConverters = false;
156 private IVerticalRuler fCachedVerticalRuler;
157 private boolean fCachedIsVerticalRulerVisible;
159 public AdaptedSourceViewer(
161 IVerticalRuler ruler,
163 super(parent, ruler, styles); //, CompilationUnitEditor.this);
165 fCachedVerticalRuler = ruler;
166 fCachedIsVerticalRulerVisible = (ruler != null);
167 fOverviewRuler = new OverviewRuler(VERTICAL_RULER_WIDTH);
169 delayedCreateControl(parent, styles);
173 * @see ISourceViewer#showAnnotations(boolean)
175 public void showAnnotations(boolean show) {
176 fCachedIsVerticalRulerVisible = (show && fCachedVerticalRuler != null);
177 // super.showAnnotations(show);
180 public IContentAssistant getContentAssistant() {
181 return fContentAssistant;
185 * @see ITextOperationTarget#doOperation(int)
187 public void doOperation(int operation) {
189 if (getTextWidget() == null)
193 case CONTENTASSIST_PROPOSALS :
194 String msg = fContentAssistant.showPossibleCompletions();
195 setStatusLineErrorMessage(msg);
198 fIgnoreTextConverters = true;
201 fIgnoreTextConverters = true;
205 super.doOperation(operation);
208 public void insertTextConverter(ITextConverter textConverter, int index) {
209 throw new UnsupportedOperationException();
212 public void addTextConverter(ITextConverter textConverter) {
213 if (fTextConverters == null) {
214 fTextConverters = new ArrayList(1);
215 fTextConverters.add(textConverter);
216 } else if (!fTextConverters.contains(textConverter))
217 fTextConverters.add(textConverter);
220 public void removeTextConverter(ITextConverter textConverter) {
221 if (fTextConverters != null) {
222 fTextConverters.remove(textConverter);
223 if (fTextConverters.size() == 0)
224 fTextConverters = null;
229 * @see TextViewer#customizeDocumentCommand(DocumentCommand)
231 protected void customizeDocumentCommand(DocumentCommand command) {
232 super.customizeDocumentCommand(command);
233 if (!fIgnoreTextConverters && fTextConverters != null) {
234 for (Iterator e = fTextConverters.iterator(); e.hasNext();)
235 ((ITextConverter) e.next()).customizeDocumentCommand(
239 fIgnoreTextConverters = false;
242 public IVerticalRuler getVerticalRuler() {
243 return fCachedVerticalRuler;
246 public boolean isVerticalRulerVisible() {
247 return fCachedIsVerticalRulerVisible;
250 public OverviewRuler getOverviewRuler() {
251 return fOverviewRuler;
255 * @see TextViewer#createControl(Composite, int)
257 protected void createControl(Composite parent, int styles) {
261 protected void delayedCreateControl(Composite parent, int styles) {
263 super.createControl(parent, styles);
265 Control control = getControl();
266 if (control instanceof Composite) {
267 Composite composite = (Composite) control;
268 composite.setLayout(new AdaptedRulerLayout(GAP_SIZE, this));
269 fOverviewRuler.createControl(composite, this);
273 protected void ensureOverviewHoverManagerInstalled() {
274 if (fOverviewRulerHoveringController == null
275 && fAnnotationHover != null
276 && fHoverControlCreator != null) {
277 fOverviewRulerHoveringController =
278 new OverviewRulerHoverManager(
282 fHoverControlCreator);
283 fOverviewRulerHoveringController.install(fOverviewRuler.getControl());
287 public void hideOverviewRuler() {
288 fIsOverviewRulerVisible = false;
289 Control control = getControl();
290 if (control instanceof Composite) {
291 Composite composite = (Composite) control;
294 if (fOverviewRulerHoveringController != null) {
295 fOverviewRulerHoveringController.dispose();
296 fOverviewRulerHoveringController = null;
300 public void showOverviewRuler() {
301 fIsOverviewRulerVisible = true;
302 Control control = getControl();
303 if (control instanceof Composite) {
304 Composite composite = (Composite) control;
307 ensureOverviewHoverManagerInstalled();
310 public boolean isOverviewRulerVisible() {
311 return fIsOverviewRulerVisible;
315 * @see ISourceViewer#setDocument(IDocument, IAnnotationModel, int, int)
317 public void setDocument(
319 IAnnotationModel annotationModel,
320 int visibleRegionOffset,
321 int visibleRegionLength) {
326 visibleRegionLength);
327 fOverviewRuler.setModel(annotationModel);
330 // http://dev.eclipse.org/bugs/show_bug.cgi?id=19270
331 public void updateIndentationPrefixes() {
332 SourceViewerConfiguration configuration = getSourceViewerConfiguration();
333 String[] types = configuration.getConfiguredContentTypes(this);
334 for (int i = 0; i < types.length; i++) {
335 String[] prefixes = configuration.getIndentPrefixes(this, types[i]);
336 if (prefixes != null && prefixes.length > 0)
337 setIndentPrefixes(prefixes, types[i]);
342 * @see IWidgetTokenOwner#requestWidgetToken(IWidgetTokenKeeper)
344 public boolean requestWidgetToken(IWidgetTokenKeeper requester) {
345 if (WorkbenchHelp.isContextHelpDisplayed())
347 return super.requestWidgetToken(requester);
351 * @see org.eclipse.jface.text.source.ISourceViewer#configure(org.eclipse.jface.text.source.SourceViewerConfiguration)
353 public void configure(SourceViewerConfiguration configuration) {
354 super.configure(configuration);
355 // prependAutoEditStrategy(new SmartBracesAutoEditStrategy(this), IDocument.DEFAULT_CONTENT_TYPE);
358 protected void handleDispose() {
359 fOverviewRuler = null;
361 if (fOverviewRulerHoveringController != null) {
362 fOverviewRulerHoveringController.dispose();
363 fOverviewRulerHoveringController = null;
366 super.handleDispose();
371 static class TabConverter implements ITextConverter {
373 private int fTabRatio;
374 private ILineTracker fLineTracker;
376 public TabConverter() {
379 public void setNumberOfSpacesPerTab(int ratio) {
383 public void setLineTracker(ILineTracker lineTracker) {
384 fLineTracker = lineTracker;
387 private int insertTabString(StringBuffer buffer, int offsetInLine) {
392 int remainder = offsetInLine % fTabRatio;
393 remainder = fTabRatio - remainder;
394 for (int i = 0; i < remainder; i++)
399 public void customizeDocumentCommand(
401 DocumentCommand command) {
402 String text = command.text;
406 int index = text.indexOf('\t');
409 StringBuffer buffer = new StringBuffer();
411 fLineTracker.set(command.text);
412 int lines = fLineTracker.getNumberOfLines();
416 for (int i = 0; i < lines; i++) {
418 int offset = fLineTracker.getLineOffset(i);
419 int endOffset = offset + fLineTracker.getLineLength(i);
420 String line = text.substring(offset, endOffset);
425 document.getLineInformationOfOffset(command.offset);
426 position = command.offset - firstLine.getOffset();
429 int length = line.length();
430 for (int j = 0; j < length; j++) {
431 char c = line.charAt(j);
433 position += insertTabString(buffer, position);
442 command.text = buffer.toString();
444 } catch (BadLocationException x) {
450 private static class ExitPolicy implements LinkedPositionUI.ExitPolicy {
452 final char fExitCharacter;
454 public ExitPolicy(char exitCharacter) {
455 fExitCharacter= exitCharacter;
459 * @see org.phpeclipse.phpdt.internal.ui.text.link.LinkedPositionUI.ExitPolicy#doExit(org.phpeclipse.phpdt.internal.ui.text.link.LinkedPositionManager, org.eclipse.swt.events.VerifyEvent, int, int)
461 public ExitFlags doExit(LinkedPositionManager manager, VerifyEvent event, int offset, int length) {
463 if (event.character == fExitCharacter) {
464 if (manager.anyPositionIncludes(offset, length))
465 return new ExitFlags(LinkedPositionUI.COMMIT| LinkedPositionUI.UPDATE_CARET, false);
467 return new ExitFlags(LinkedPositionUI.COMMIT, true);
470 switch (event.character) {
472 if (manager.getFirstPosition().length == 0)
473 return new ExitFlags(0, false);
479 return new ExitFlags(LinkedPositionUI.COMMIT, true);
487 private class BracketInserter implements VerifyKeyListener, LinkedPositionUI.ExitListener {
489 private boolean fCloseBrackets= true;
490 private boolean fCloseStrings= true;
495 public void setCloseBracketsEnabled(boolean enabled) {
496 fCloseBrackets= enabled;
499 public void setCloseStringsEnabled(boolean enabled) {
500 fCloseStrings= enabled;
503 private boolean hasIdentifierToTheRight(IDocument document, int offset) {
506 IRegion endLine= document.getLineInformationOfOffset(end);
507 int maxEnd= endLine.getOffset() + endLine.getLength();
508 while (end != maxEnd && Character.isWhitespace(document.getChar(end)))
511 return end != maxEnd && Character.isJavaIdentifierPart(document.getChar(end));
513 } catch (BadLocationException e) {
519 private boolean hasIdentifierToTheLeft(IDocument document, int offset) {
522 IRegion startLine= document.getLineInformationOfOffset(start);
523 int minStart= startLine.getOffset();
524 while (start != minStart && Character.isWhitespace(document.getChar(start - 1)))
527 return start != minStart && Character.isJavaIdentifierPart(document.getChar(start - 1));
529 } catch (BadLocationException e) {
534 private boolean hasCharacterToTheRight(IDocument document, int offset, char character) {
537 IRegion endLine= document.getLineInformationOfOffset(end);
538 int maxEnd= endLine.getOffset() + endLine.getLength();
539 while (end != maxEnd && Character.isWhitespace(document.getChar(end)))
542 return end != maxEnd && document.getChar(end) == character;
545 } catch (BadLocationException e) {
552 * @see org.eclipse.swt.custom.VerifyKeyListener#verifyKey(org.eclipse.swt.events.VerifyEvent)
554 public void verifyKey(VerifyEvent event) {
559 final ISourceViewer sourceViewer= getSourceViewer();
560 IDocument document= sourceViewer.getDocument();
562 final Point selection= sourceViewer.getSelectedRange();
563 final int offset= selection.x;
564 final int length= selection.y;
566 switch (event.character) {
568 if (hasCharacterToTheRight(document, offset + length, '('))
576 if (hasIdentifierToTheRight(document, offset + length))
582 if (event.character == '"') {
585 if (hasIdentifierToTheLeft(document, offset) || hasIdentifierToTheRight(document, offset + length))
590 ITypedRegion partition= document.getPartition(offset);
591 if (! IDocument.DEFAULT_CONTENT_TYPE.equals(partition.getType()) && partition.getOffset() != offset)
594 final char character= event.character;
595 final char closingCharacter= getPeerCharacter(character);
596 final StringBuffer buffer= new StringBuffer();
597 buffer.append(character);
598 buffer.append(closingCharacter);
600 document.replace(offset, length, buffer.toString());
602 LinkedPositionManager manager= new LinkedPositionManager(document);
603 manager.addPosition(offset + 1, 0);
608 LinkedPositionUI editor= new LinkedPositionUI(sourceViewer, manager);
609 editor.setCancelListener(this);
610 editor.setExitPolicy(new ExitPolicy(closingCharacter));
611 editor.setFinalCaretOffset(offset + 2);
614 IRegion newSelection= editor.getSelectedRegion();
615 sourceViewer.setSelectedRange(newSelection.getOffset(), newSelection.getLength());
619 } catch (BadLocationException e) {
626 * @see org.phpeclipse.phpdt.internal.ui.text.link.LinkedPositionUI.ExitListener#exit(boolean)
628 public void exit(boolean accept) {
634 final ISourceViewer sourceViewer= getSourceViewer();
635 IDocument document= sourceViewer.getDocument();
636 document.replace(fOffset, fLength, null);
637 } catch (BadLocationException e) {
642 /** The editor's paint manager */
643 private PaintManager fPaintManager;
644 /** The editor's bracket painter */
645 private BracketPainter fBracketPainter;
646 /** The editor's bracket matcher */
647 private PHPPairMatcher fBracketMatcher;
648 /** The editor's line painter */
649 private LinePainter fLinePainter;
650 /** The editor's print margin ruler painter */
651 private PrintMarginPainter fPrintMarginPainter;
652 /** The editor's problem painter */
653 private ProblemPainter fProblemPainter;
654 /** The editor's tab converter */
655 private TabConverter fTabConverter;
656 /** History for structure select action */
657 //private SelectionHistory fSelectionHistory;
659 /** The preference property change listener for php core. */
660 private IPropertyChangeListener fPropertyChangeListener= new PropertyChangeListener();
661 /** The remembered selection */
662 private ITextSelection fRememberedSelection;
663 /** The remembered php element offset */
664 private int fRememberedElementOffset;
665 /** The bracket inserter. */
666 private BracketInserter fBracketInserter= new BracketInserter();
668 private class PropertyChangeListener implements IPropertyChangeListener {
670 * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
672 public void propertyChange(org.eclipse.core.runtime.Preferences.PropertyChangeEvent event) {
673 handlePreferencePropertyChanged(event);
676 /* Preference key for code formatter tab size */
677 private final static String CODE_FORMATTER_TAB_SIZE =
678 PHPCore.FORMATTER_TAB_SIZE;
679 /** Preference key for matching brackets */
680 private final static String MATCHING_BRACKETS =
681 PreferenceConstants.EDITOR_MATCHING_BRACKETS;
682 /** Preference key for matching brackets color */
683 private final static String MATCHING_BRACKETS_COLOR =
684 PreferenceConstants.EDITOR_MATCHING_BRACKETS_COLOR;
685 /** Preference key for highlighting current line */
686 private final static String CURRENT_LINE =
687 PreferenceConstants.EDITOR_CURRENT_LINE;
688 /** Preference key for highlight color of current line */
689 private final static String CURRENT_LINE_COLOR =
690 PreferenceConstants.EDITOR_CURRENT_LINE_COLOR;
691 /** Preference key for showing print marging ruler */
692 private final static String PRINT_MARGIN =
693 PreferenceConstants.EDITOR_PRINT_MARGIN;
694 /** Preference key for print margin ruler color */
695 private final static String PRINT_MARGIN_COLOR =
696 PreferenceConstants.EDITOR_PRINT_MARGIN_COLOR;
697 /** Preference key for print margin ruler column */
698 private final static String PRINT_MARGIN_COLUMN =
699 PreferenceConstants.EDITOR_PRINT_MARGIN_COLUMN;
700 /** Preference key for inserting spaces rather than tabs */
701 private final static String SPACES_FOR_TABS =
702 PreferenceConstants.EDITOR_SPACES_FOR_TABS;
703 /** Preference key for error indication */
704 private final static String ERROR_INDICATION =
705 PreferenceConstants.EDITOR_PROBLEM_INDICATION;
706 /** Preference key for error color */
707 private final static String ERROR_INDICATION_COLOR =
708 PreferenceConstants.EDITOR_PROBLEM_INDICATION_COLOR;
709 /** Preference key for warning indication */
710 private final static String WARNING_INDICATION =
711 PreferenceConstants.EDITOR_WARNING_INDICATION;
712 /** Preference key for warning color */
713 private final static String WARNING_INDICATION_COLOR =
714 PreferenceConstants.EDITOR_WARNING_INDICATION_COLOR;
715 /** Preference key for task indication */
716 private final static String TASK_INDICATION =
717 PreferenceConstants.EDITOR_TASK_INDICATION;
718 /** Preference key for task color */
719 private final static String TASK_INDICATION_COLOR =
720 PreferenceConstants.EDITOR_TASK_INDICATION_COLOR;
721 /** Preference key for bookmark indication */
722 private final static String BOOKMARK_INDICATION =
723 PreferenceConstants.EDITOR_BOOKMARK_INDICATION;
724 /** Preference key for bookmark color */
725 private final static String BOOKMARK_INDICATION_COLOR =
726 PreferenceConstants.EDITOR_BOOKMARK_INDICATION_COLOR;
727 /** Preference key for search result indication */
728 private final static String SEARCH_RESULT_INDICATION =
729 PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION;
730 /** Preference key for search result color */
731 private final static String SEARCH_RESULT_INDICATION_COLOR =
732 PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION_COLOR;
733 /** Preference key for unknown annotation indication */
734 private final static String UNKNOWN_INDICATION =
735 PreferenceConstants.EDITOR_UNKNOWN_INDICATION;
736 /** Preference key for unknown annotation color */
737 private final static String UNKNOWN_INDICATION_COLOR =
738 PreferenceConstants.EDITOR_UNKNOWN_INDICATION_COLOR;
739 /** Preference key for linked position color */
740 private final static String LINKED_POSITION_COLOR =
741 PreferenceConstants.EDITOR_LINKED_POSITION_COLOR;
742 /** Preference key for shwoing the overview ruler */
743 private final static String OVERVIEW_RULER =
744 PreferenceConstants.EDITOR_OVERVIEW_RULER;
746 /** Preference key for error indication in overview ruler */
747 private final static String ERROR_INDICATION_IN_OVERVIEW_RULER =
748 PreferenceConstants.EDITOR_ERROR_INDICATION_IN_OVERVIEW_RULER;
749 /** Preference key for warning indication in overview ruler */
750 private final static String WARNING_INDICATION_IN_OVERVIEW_RULER =
751 PreferenceConstants.EDITOR_WARNING_INDICATION_IN_OVERVIEW_RULER;
752 /** Preference key for task indication in overview ruler */
753 private final static String TASK_INDICATION_IN_OVERVIEW_RULER =
754 PreferenceConstants.EDITOR_TASK_INDICATION_IN_OVERVIEW_RULER;
755 /** Preference key for bookmark indication in overview ruler */
756 private final static String BOOKMARK_INDICATION_IN_OVERVIEW_RULER =
757 PreferenceConstants.EDITOR_BOOKMARK_INDICATION_IN_OVERVIEW_RULER;
758 /** Preference key for search result indication in overview ruler */
759 private final static String SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER =
760 PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER;
761 /** Preference key for unknown annotation indication in overview ruler */
762 private final static String UNKNOWN_INDICATION_IN_OVERVIEW_RULER =
763 PreferenceConstants.EDITOR_UNKNOWN_INDICATION_IN_OVERVIEW_RULER;
764 /** Preference key for automatically closing strings */
765 private final static String CLOSE_STRINGS= PreferenceConstants.EDITOR_CLOSE_STRINGS;
766 /** Preference key for automatically wrapping Java strings */
767 private final static String WRAP_STRINGS= PreferenceConstants.EDITOR_WRAP_STRINGS;
768 /** Preference key for automatically closing brackets and parenthesis */
769 private final static String CLOSE_BRACKETS= PreferenceConstants.EDITOR_CLOSE_BRACKETS;
770 /** Preference key for automatically closing phpdocs and comments */
771 private final static String CLOSE_JAVADOCS= PreferenceConstants.EDITOR_CLOSE_JAVADOCS;
772 /** Preference key for automatically adding phpdoc tags */
773 private final static String ADD_JAVADOC_TAGS= PreferenceConstants.EDITOR_ADD_JAVADOC_TAGS;
774 /** Preference key for automatically formatting phpdocs */
775 private final static String FORMAT_JAVADOCS= PreferenceConstants.EDITOR_FORMAT_JAVADOCS;
776 /** Preference key for smart paste */
777 private final static String SMART_PASTE= PreferenceConstants.EDITOR_SMART_PASTE;
778 private final static class AnnotationInfo {
779 public String fColorPreference;
780 public String fOverviewRulerPreference;
781 public String fEditorPreference;
784 private final static Map ANNOTATION_MAP;
788 ANNOTATION_MAP = new HashMap();
790 info = new AnnotationInfo();
791 info.fColorPreference = TASK_INDICATION_COLOR;
792 info.fOverviewRulerPreference = TASK_INDICATION_IN_OVERVIEW_RULER;
793 info.fEditorPreference = TASK_INDICATION;
794 ANNOTATION_MAP.put(AnnotationType.TASK, info);
796 info = new AnnotationInfo();
797 info.fColorPreference = ERROR_INDICATION_COLOR;
798 info.fOverviewRulerPreference = ERROR_INDICATION_IN_OVERVIEW_RULER;
799 info.fEditorPreference = ERROR_INDICATION;
800 ANNOTATION_MAP.put(AnnotationType.ERROR, info);
802 info = new AnnotationInfo();
803 info.fColorPreference = WARNING_INDICATION_COLOR;
804 info.fOverviewRulerPreference = WARNING_INDICATION_IN_OVERVIEW_RULER;
805 info.fEditorPreference = WARNING_INDICATION;
806 ANNOTATION_MAP.put(AnnotationType.WARNING, info);
808 info = new AnnotationInfo();
809 info.fColorPreference = BOOKMARK_INDICATION_COLOR;
810 info.fOverviewRulerPreference = BOOKMARK_INDICATION_IN_OVERVIEW_RULER;
811 info.fEditorPreference = BOOKMARK_INDICATION;
812 ANNOTATION_MAP.put(AnnotationType.BOOKMARK, info);
814 info = new AnnotationInfo();
815 info.fColorPreference = SEARCH_RESULT_INDICATION_COLOR;
816 info.fOverviewRulerPreference = SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER;
817 info.fEditorPreference = SEARCH_RESULT_INDICATION;
818 ANNOTATION_MAP.put(AnnotationType.SEARCH_RESULT, info);
820 info = new AnnotationInfo();
821 info.fColorPreference = UNKNOWN_INDICATION_COLOR;
822 info.fOverviewRulerPreference = UNKNOWN_INDICATION_IN_OVERVIEW_RULER;
823 info.fEditorPreference = UNKNOWN_INDICATION;
824 ANNOTATION_MAP.put(AnnotationType.UNKNOWN, info);
827 private final static AnnotationType[] ANNOTATION_LAYERS =
828 new AnnotationType[] {
829 AnnotationType.UNKNOWN,
830 AnnotationType.BOOKMARK,
832 AnnotationType.SEARCH_RESULT,
833 AnnotationType.WARNING,
834 AnnotationType.ERROR };
837 * Creates a new php unit editor.
839 public PHPUnitEditor() {
841 setDocumentProvider(PHPeclipsePlugin.getDefault().getCompilationUnitDocumentProvider());
842 setEditorContextMenuId("#PHPEditorContext"); //$NON-NLS-1$
843 setRulerContextMenuId("#PHPRulerContext"); //$NON-NLS-1$
847 public void createPartControl(Composite parent) {
848 super.createPartControl(parent);
850 fPaintManager = new PaintManager(getSourceViewer());
852 LinePainter linePainter;
853 linePainter = new LinePainter(getSourceViewer());
855 linePainter.setHighlightColor(
856 new Color(Display.getCurrent(), 225, 235, 224));
858 fPaintManager.addPainter(linePainter);
861 if (isBracketHighlightingEnabled())
862 startBracketHighlighting();
863 if (isLineHighlightingEnabled())
864 startLineHighlighting();
865 if (isPrintMarginVisible())
869 Iterator e= ANNOTATION_MAP.keySet().iterator();
870 while (e.hasNext()) {
871 AnnotationType type= (AnnotationType) e.next();
872 if (isAnnotationIndicationEnabled(type))
873 startAnnotationIndication(type);
876 if (isTabConversionEnabled())
877 startTabConversion();
879 if (isOverviewRulerVisible())
883 Preferences preferences= PHPeclipsePlugin.getDefault().getPluginPreferences();
884 preferences.addPropertyChangeListener(fPropertyChangeListener);
886 IPreferenceStore preferenceStore= getPreferenceStore();
887 boolean closeBrackets= preferenceStore.getBoolean(CLOSE_BRACKETS);
888 boolean closeStrings= preferenceStore.getBoolean(CLOSE_STRINGS);
890 fBracketInserter.setCloseBracketsEnabled(closeBrackets);
891 fBracketInserter.setCloseStringsEnabled(closeStrings);
893 ISourceViewer sourceViewer= getSourceViewer();
894 if (sourceViewer instanceof ITextViewerExtension)
895 ((ITextViewerExtension) sourceViewer).prependVerifyKeyListener(fBracketInserter);
899 private static char getPeerCharacter(char character) {
917 throw new IllegalArgumentException();
922 * @see AbstractTextEditor#doSetInput(IEditorInput)
924 protected void doSetInput(IEditorInput input) throws CoreException {
925 super.doSetInput(input);
926 configureTabConverter();
929 private void startBracketHighlighting() {
930 if (fBracketPainter == null) {
931 ISourceViewer sourceViewer = getSourceViewer();
932 fBracketPainter = new BracketPainter(sourceViewer);
933 fBracketPainter.setHighlightColor(getColor(MATCHING_BRACKETS_COLOR));
934 fPaintManager.addPainter(fBracketPainter);
938 private void stopBracketHighlighting() {
939 if (fBracketPainter != null) {
940 fPaintManager.removePainter(fBracketPainter);
941 fBracketPainter.deactivate(true);
942 fBracketPainter.dispose();
943 fBracketPainter = null;
947 private boolean isBracketHighlightingEnabled() {
948 IPreferenceStore store = getPreferenceStore();
949 return store.getBoolean(MATCHING_BRACKETS);
952 private void startLineHighlighting() {
953 if (fLinePainter == null) {
954 ISourceViewer sourceViewer = getSourceViewer();
955 fLinePainter = new LinePainter(sourceViewer);
956 fLinePainter.setHighlightColor(getColor(CURRENT_LINE_COLOR));
957 fPaintManager.addPainter(fLinePainter);
961 private void stopLineHighlighting() {
962 if (fLinePainter != null) {
963 fPaintManager.removePainter(fLinePainter);
964 fLinePainter.deactivate(true);
965 fLinePainter.dispose();
970 private boolean isLineHighlightingEnabled() {
971 IPreferenceStore store = getPreferenceStore();
972 return store.getBoolean(CURRENT_LINE);
975 private void showPrintMargin() {
976 if (fPrintMarginPainter == null) {
977 fPrintMarginPainter = new PrintMarginPainter(getSourceViewer());
978 fPrintMarginPainter.setMarginRulerColor(getColor(PRINT_MARGIN_COLOR));
979 fPrintMarginPainter.setMarginRulerColumn(
980 getPreferenceStore().getInt(PRINT_MARGIN_COLUMN));
981 fPaintManager.addPainter(fPrintMarginPainter);
985 private void hidePrintMargin() {
986 if (fPrintMarginPainter != null) {
987 fPaintManager.removePainter(fPrintMarginPainter);
988 fPrintMarginPainter.deactivate(true);
989 fPrintMarginPainter.dispose();
990 fPrintMarginPainter = null;
994 private boolean isPrintMarginVisible() {
995 IPreferenceStore store = getPreferenceStore();
996 return store.getBoolean(PRINT_MARGIN);
999 private void startAnnotationIndication(AnnotationType annotationType) {
1000 if (fProblemPainter == null) {
1001 fProblemPainter = new ProblemPainter(this, getSourceViewer());
1002 fPaintManager.addPainter(fProblemPainter);
1004 fProblemPainter.setColor(annotationType, getColor(annotationType));
1005 fProblemPainter.paintAnnotations(annotationType, true);
1006 fProblemPainter.paint(IPainter.CONFIGURATION);
1009 private void shutdownAnnotationIndication() {
1010 if (fProblemPainter != null) {
1012 if (!fProblemPainter.isPaintingAnnotations()) {
1013 fPaintManager.removePainter(fProblemPainter);
1014 fProblemPainter.deactivate(true);
1015 fProblemPainter.dispose();
1016 fProblemPainter = null;
1018 fProblemPainter.paint(IPainter.CONFIGURATION);
1023 private void stopAnnotationIndication(AnnotationType annotationType) {
1024 if (fProblemPainter != null) {
1025 fProblemPainter.paintAnnotations(annotationType, false);
1026 shutdownAnnotationIndication();
1030 private boolean isAnnotationIndicationEnabled(AnnotationType annotationType) {
1031 IPreferenceStore store = getPreferenceStore();
1032 AnnotationInfo info = (AnnotationInfo) ANNOTATION_MAP.get(annotationType);
1034 return store.getBoolean(info.fEditorPreference);
1038 private boolean isAnnotationIndicationInOverviewRulerEnabled(AnnotationType annotationType) {
1039 IPreferenceStore store = getPreferenceStore();
1040 AnnotationInfo info = (AnnotationInfo) ANNOTATION_MAP.get(annotationType);
1042 return store.getBoolean(info.fOverviewRulerPreference);
1046 private void showAnnotationIndicationInOverviewRuler(
1047 AnnotationType annotationType,
1049 AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
1050 OverviewRuler ruler = asv.getOverviewRuler();
1051 if (ruler != null) {
1052 ruler.setColor(annotationType, getColor(annotationType));
1053 ruler.showAnnotation(annotationType, show);
1058 private void setColorInOverviewRuler(
1059 AnnotationType annotationType,
1061 AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
1062 OverviewRuler ruler = asv.getOverviewRuler();
1063 if (ruler != null) {
1064 ruler.setColor(annotationType, color);
1069 private void configureTabConverter() {
1070 if (fTabConverter != null) {
1071 IDocumentProvider provider = getDocumentProvider();
1072 if (provider instanceof PHPDocumentProvider) {
1073 PHPDocumentProvider cup = (PHPDocumentProvider) provider;
1074 fTabConverter.setLineTracker(cup.createLineTracker(getEditorInput()));
1079 private int getTabSize() {
1080 Preferences preferences =
1081 PHPeclipsePlugin.getDefault().getPluginPreferences();
1082 return preferences.getInt(CODE_FORMATTER_TAB_SIZE);
1085 private void startTabConversion() {
1086 if (fTabConverter == null) {
1087 fTabConverter = new TabConverter();
1088 configureTabConverter();
1089 fTabConverter.setNumberOfSpacesPerTab(getTabSize());
1090 AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
1091 asv.addTextConverter(fTabConverter);
1092 // http://dev.eclipse.org/bugs/show_bug.cgi?id=19270
1093 asv.updateIndentationPrefixes();
1097 private void stopTabConversion() {
1098 if (fTabConverter != null) {
1099 AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
1100 asv.removeTextConverter(fTabConverter);
1101 // http://dev.eclipse.org/bugs/show_bug.cgi?id=19270
1102 asv.updateIndentationPrefixes();
1103 fTabConverter = null;
1107 private boolean isTabConversionEnabled() {
1108 IPreferenceStore store = getPreferenceStore();
1109 return store.getBoolean(SPACES_FOR_TABS);
1112 private void showOverviewRuler() {
1113 AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
1114 asv.showOverviewRuler();
1116 OverviewRuler overviewRuler = asv.getOverviewRuler();
1117 if (overviewRuler != null) {
1118 for (int i = 0; i < ANNOTATION_LAYERS.length; i++) {
1119 AnnotationType type = ANNOTATION_LAYERS[i];
1120 overviewRuler.setLayer(type, i);
1121 if (isAnnotationIndicationInOverviewRulerEnabled(type))
1122 showAnnotationIndicationInOverviewRuler(type, true);
1127 private void hideOverviewRuler() {
1128 AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
1129 asv.hideOverviewRuler();
1132 private boolean isOverviewRulerVisible() {
1133 IPreferenceStore store = getPreferenceStore();
1134 return store.getBoolean(OVERVIEW_RULER);
1137 private Color getColor(String key) {
1138 RGB rgb = PreferenceConverter.getColor(getPreferenceStore(), key);
1139 return getColor(rgb);
1142 private Color getColor(RGB rgb) {
1143 JavaTextTools textTools = PHPeclipsePlugin.getDefault().getJavaTextTools();
1144 return textTools.getColorManager().getColor(rgb);
1147 private Color getColor(AnnotationType annotationType) {
1148 AnnotationInfo info = (AnnotationInfo) ANNOTATION_MAP.get(annotationType);
1150 return getColor(info.fColorPreference);
1154 public void dispose() {
1155 ISourceViewer sourceViewer= getSourceViewer();
1156 if (sourceViewer instanceof ITextViewerExtension)
1157 ((ITextViewerExtension) sourceViewer).removeVerifyKeyListener(fBracketInserter);
1159 if (fPropertyChangeListener != null) {
1160 Preferences preferences= PHPeclipsePlugin.getDefault().getPluginPreferences();
1161 preferences.removePropertyChangeListener(fPropertyChangeListener);
1162 fPropertyChangeListener= null;
1166 // if (fJavaEditorErrorTickUpdater != null) {
1167 // fJavaEditorErrorTickUpdater.dispose();
1168 // fJavaEditorErrorTickUpdater= null;
1171 // if (fSelectionHistory != null)
1172 // fSelectionHistory.dispose();
1174 if (fPaintManager != null) {
1175 fPaintManager.dispose();
1176 fPaintManager = null;
1179 if (fActionGroups != null)
1180 fActionGroups.dispose();
1185 protected AnnotationType getAnnotationType(String preferenceKey) {
1186 Iterator e= ANNOTATION_MAP.keySet().iterator();
1187 while (e.hasNext()) {
1188 AnnotationType type= (AnnotationType) e.next();
1189 AnnotationInfo info= (AnnotationInfo) ANNOTATION_MAP.get(type);
1191 if (preferenceKey.equals(info.fColorPreference) || preferenceKey.equals(info.fEditorPreference) || preferenceKey.equals(info.fOverviewRulerPreference))
1199 * @see AbstractTextEditor#handlePreferenceStoreChanged(PropertyChangeEvent)
1201 protected void handlePreferenceStoreChanged(PropertyChangeEvent event) {
1205 AdaptedSourceViewer asv= (AdaptedSourceViewer) getSourceViewer();
1208 String p= event.getProperty();
1210 if (CLOSE_BRACKETS.equals(p)) {
1211 fBracketInserter.setCloseBracketsEnabled(getPreferenceStore().getBoolean(p));
1215 if (CLOSE_STRINGS.equals(p)) {
1216 fBracketInserter.setCloseStringsEnabled(getPreferenceStore().getBoolean(p));
1220 if (SPACES_FOR_TABS.equals(p)) {
1221 if (isTabConversionEnabled())
1222 startTabConversion();
1224 stopTabConversion();
1228 if (MATCHING_BRACKETS.equals(p)) {
1229 if (isBracketHighlightingEnabled())
1230 startBracketHighlighting();
1232 stopBracketHighlighting();
1236 if (MATCHING_BRACKETS_COLOR.equals(p)) {
1237 if (fBracketPainter != null)
1238 fBracketPainter.setHighlightColor(getColor(MATCHING_BRACKETS_COLOR));
1242 if (CURRENT_LINE.equals(p)) {
1243 if (isLineHighlightingEnabled())
1244 startLineHighlighting();
1246 stopLineHighlighting();
1250 if (CURRENT_LINE_COLOR.equals(p)) {
1251 if (fLinePainter != null) {
1252 stopLineHighlighting();
1253 startLineHighlighting();
1258 if (PRINT_MARGIN.equals(p)) {
1259 if (isPrintMarginVisible())
1266 if (PRINT_MARGIN_COLOR.equals(p)) {
1267 if (fPrintMarginPainter != null)
1268 fPrintMarginPainter.setMarginRulerColor(getColor(PRINT_MARGIN_COLOR));
1272 if (PRINT_MARGIN_COLUMN.equals(p)) {
1273 if (fPrintMarginPainter != null)
1274 fPrintMarginPainter.setMarginRulerColumn(getPreferenceStore().getInt(PRINT_MARGIN_COLUMN));
1278 if (OVERVIEW_RULER.equals(p)) {
1279 if (isOverviewRulerVisible())
1280 showOverviewRuler();
1282 hideOverviewRuler();
1286 AnnotationType type= getAnnotationType(p);
1289 AnnotationInfo info= (AnnotationInfo) ANNOTATION_MAP.get(type);
1290 if (info.fColorPreference.equals(p)) {
1291 Color color= getColor(type);
1292 if (fProblemPainter != null) {
1293 fProblemPainter.setColor(type, color);
1294 fProblemPainter.paint(IPainter.CONFIGURATION);
1296 setColorInOverviewRuler(type, color);
1300 if (info.fEditorPreference.equals(p)) {
1301 if (isAnnotationIndicationEnabled(type))
1302 startAnnotationIndication(type);
1304 stopAnnotationIndication(type);
1308 if (info.fOverviewRulerPreference.equals(p)) {
1309 if (isAnnotationIndicationInOverviewRulerEnabled(type))
1310 showAnnotationIndicationInOverviewRuler(type, true);
1312 showAnnotationIndicationInOverviewRuler(type, false);
1317 IContentAssistant c= asv.getContentAssistant();
1318 if (c instanceof ContentAssistant)
1319 ContentAssistPreference.changeConfiguration((ContentAssistant) c, getPreferenceStore(), event);
1323 super.handlePreferenceStoreChanged(event);
1328 * Handles a property change event describing a change
1329 * of the php core's preferences and updates the preference
1330 * related editor properties.
1332 * @param event the property change event
1334 protected void handlePreferencePropertyChanged(org.eclipse.core.runtime.Preferences.PropertyChangeEvent event) {
1335 AdaptedSourceViewer asv= (AdaptedSourceViewer) getSourceViewer();
1337 String p= event.getProperty();
1338 if (CODE_FORMATTER_TAB_SIZE.equals(p)) {
1339 asv.updateIndentationPrefixes();
1340 if (fTabConverter != null)
1341 fTabConverter.setNumberOfSpacesPerTab(getTabSize());
1347 * @see PHPEditor#createJavaSourceViewer(Composite, IVerticalRuler, int)
1349 protected ISourceViewer createJavaSourceViewer(Composite parent, IVerticalRuler ruler, int styles) {
1350 return new AdaptedSourceViewer(parent, ruler, styles);
1353 private boolean isValidSelection(int offset, int length) {
1354 IDocumentProvider provider= getDocumentProvider();
1355 if (provider != null) {
1356 IDocument document= provider.getDocument(getEditorInput());
1357 if (document != null) {
1358 int end= offset + length;
1359 int documentLength= document.getLength();
1360 return 0 <= offset && offset <= documentLength && 0 <= end && end <= documentLength;
1367 * @see AbstractTextEditor#canHandleMove(IEditorInput, IEditorInput)
1369 protected boolean canHandleMove(IEditorInput originalElement, IEditorInput movedElement) {
1371 String oldExtension= ""; //$NON-NLS-1$
1372 if (originalElement instanceof IFileEditorInput) {
1373 IFile file= ((IFileEditorInput) originalElement).getFile();
1375 String ext= file.getFileExtension();
1381 String newExtension= ""; //$NON-NLS-1$
1382 if (movedElement instanceof IFileEditorInput) {
1383 IFile file= ((IFileEditorInput) movedElement).getFile();
1385 newExtension= file.getFileExtension();
1388 return oldExtension.equals(newExtension);