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.PHPPairMatcher;
10 import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionManager;
11 import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionUI;
12 import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionUI.ExitFlags;
13 import net.sourceforge.phpdt.ui.PreferenceConstants;
14 import net.sourceforge.phpeclipse.PHPCore;
15 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
17 import org.eclipse.core.resources.IFile;
18 import org.eclipse.core.runtime.CoreException;
19 import org.eclipse.core.runtime.Preferences;
20 import org.eclipse.core.runtime.Preferences.IPropertyChangeListener;
21 import org.eclipse.jface.preference.IPreferenceStore;
22 import org.eclipse.jface.preference.PreferenceConverter;
23 import org.eclipse.jface.text.AbstractHoverInformationControlManager;
24 import org.eclipse.jface.text.BadLocationException;
25 import org.eclipse.jface.text.DocumentCommand;
26 import org.eclipse.jface.text.IDocument;
27 import org.eclipse.jface.text.ILineTracker;
28 import org.eclipse.jface.text.IRegion;
29 import org.eclipse.jface.text.ITextSelection;
30 import org.eclipse.jface.text.ITextViewerExtension;
31 import org.eclipse.jface.text.ITypedRegion;
32 import org.eclipse.jface.text.IWidgetTokenKeeper;
33 import org.eclipse.jface.text.contentassist.IContentAssistant;
34 import org.eclipse.jface.text.source.IAnnotationModel;
35 import org.eclipse.jface.text.source.ISourceViewer;
36 import org.eclipse.jface.text.source.IVerticalRuler;
37 import org.eclipse.jface.text.source.SourceViewer;
38 import org.eclipse.jface.text.source.SourceViewerConfiguration;
39 import org.eclipse.jface.util.PropertyChangeEvent;
40 import org.eclipse.swt.SWT;
41 import org.eclipse.swt.custom.StyledText;
42 import org.eclipse.swt.custom.VerifyKeyListener;
43 import org.eclipse.swt.events.VerifyEvent;
44 import org.eclipse.swt.graphics.Color;
45 import org.eclipse.swt.graphics.Point;
46 import org.eclipse.swt.graphics.RGB;
47 import org.eclipse.swt.graphics.Rectangle;
48 import org.eclipse.swt.widgets.Composite;
49 import org.eclipse.swt.widgets.Control;
50 import org.eclipse.swt.widgets.Display;
51 import org.eclipse.swt.widgets.Layout;
52 import org.eclipse.ui.IEditorInput;
53 import org.eclipse.ui.IFileEditorInput;
54 import org.eclipse.ui.help.WorkbenchHelp;
55 import org.eclipse.ui.texteditor.IDocumentProvider;
57 /**********************************************************************
58 Copyright (c) 2000, 2002 IBM Corp. and others.
59 All rights reserved. This program and the accompanying materials
60 are made available under the terms of the Common Public License v1.0
61 which accompanies this distribution, and is available at
62 http://www.eclipse.org/legal/cpl-v10.html
65 IBM Corporation - Initial implementation
66 Klaus Hartlage - www.eclipseproject.de
67 **********************************************************************/
69 * PHP specific text editor.
71 public class PHPUnitEditor extends PHPEditor {
72 interface ITextConverter {
73 void customizeDocumentCommand(IDocument document, DocumentCommand command);
76 class AdaptedRulerLayout extends Layout {
79 protected AdaptedSourceViewer fAdaptedSourceViewer;
81 protected AdaptedRulerLayout(int gap, AdaptedSourceViewer asv) {
83 fAdaptedSourceViewer = asv;
86 protected Point computeSize(
91 Control[] children = composite.getChildren();
93 children[children.length
94 - 1].computeSize(SWT.DEFAULT, SWT.DEFAULT, flushCache);
95 if (fAdaptedSourceViewer.isVerticalRulerVisible())
96 s.x += fAdaptedSourceViewer.getVerticalRuler().getWidth() + fGap;
100 protected void layout(Composite composite, boolean flushCache) {
101 Rectangle clArea = composite.getClientArea();
102 if (fAdaptedSourceViewer.isVerticalRulerVisible()) {
104 StyledText textWidget = fAdaptedSourceViewer.getTextWidget();
105 Rectangle trim = textWidget.computeTrim(0, 0, 0, 0);
106 int scrollbarHeight = trim.height;
108 IVerticalRuler vr = fAdaptedSourceViewer.getVerticalRuler();
109 int vrWidth = vr.getWidth();
112 if (fAdaptedSourceViewer.isOverviewRulerVisible()) {
113 OverviewRuler or = fAdaptedSourceViewer.getOverviewRuler();
114 orWidth = or.getWidth();
115 or.getControl().setBounds(
116 clArea.width - orWidth,
119 clArea.height - 3 * scrollbarHeight);
122 textWidget.setBounds(
125 clArea.width - vrWidth - orWidth - 2 * fGap,
127 vr.getControl().setBounds(
131 clArea.height - scrollbarHeight);
134 StyledText textWidget = fAdaptedSourceViewer.getTextWidget();
135 textWidget.setBounds(0, 0, clArea.width, clArea.height);
140 class AdaptedSourceViewer
141 extends SourceViewer { // extends JavaCorrectionSourceViewer {
143 private List fTextConverters;
145 private OverviewRuler fOverviewRuler;
146 private boolean fIsOverviewRulerVisible;
147 /** The viewer's overview ruler hovering controller */
148 private AbstractHoverInformationControlManager fOverviewRulerHoveringController;
150 private boolean fIgnoreTextConverters = false;
152 private IVerticalRuler fCachedVerticalRuler;
153 private boolean fCachedIsVerticalRulerVisible;
155 public AdaptedSourceViewer(
157 IVerticalRuler ruler,
159 super(parent, ruler, styles); //, CompilationUnitEditor.this);
161 fCachedVerticalRuler = ruler;
162 fCachedIsVerticalRulerVisible = (ruler != null);
163 fOverviewRuler = new OverviewRuler(VERTICAL_RULER_WIDTH);
165 delayedCreateControl(parent, styles);
169 * @see ISourceViewer#showAnnotations(boolean)
171 public void showAnnotations(boolean show) {
172 fCachedIsVerticalRulerVisible = (show && fCachedVerticalRuler != null);
173 // super.showAnnotations(show);
176 public IContentAssistant getContentAssistant() {
177 return fContentAssistant;
181 * @see ITextOperationTarget#doOperation(int)
183 public void doOperation(int operation) {
185 if (getTextWidget() == null)
189 case CONTENTASSIST_PROPOSALS :
190 String msg = fContentAssistant.showPossibleCompletions();
191 setStatusLineErrorMessage(msg);
194 fIgnoreTextConverters = true;
197 fIgnoreTextConverters = true;
201 super.doOperation(operation);
204 public void insertTextConverter(ITextConverter textConverter, int index) {
205 throw new UnsupportedOperationException();
208 public void addTextConverter(ITextConverter textConverter) {
209 if (fTextConverters == null) {
210 fTextConverters = new ArrayList(1);
211 fTextConverters.add(textConverter);
212 } else if (!fTextConverters.contains(textConverter))
213 fTextConverters.add(textConverter);
216 public void removeTextConverter(ITextConverter textConverter) {
217 if (fTextConverters != null) {
218 fTextConverters.remove(textConverter);
219 if (fTextConverters.size() == 0)
220 fTextConverters = null;
225 * @see TextViewer#customizeDocumentCommand(DocumentCommand)
227 protected void customizeDocumentCommand(DocumentCommand command) {
228 super.customizeDocumentCommand(command);
229 if (!fIgnoreTextConverters && fTextConverters != null) {
230 for (Iterator e = fTextConverters.iterator(); e.hasNext();)
231 ((ITextConverter) e.next()).customizeDocumentCommand(
235 fIgnoreTextConverters = false;
238 public IVerticalRuler getVerticalRuler() {
239 return fCachedVerticalRuler;
242 public boolean isVerticalRulerVisible() {
243 return fCachedIsVerticalRulerVisible;
246 public OverviewRuler getOverviewRuler() {
247 return fOverviewRuler;
251 * @see TextViewer#createControl(Composite, int)
253 protected void createControl(Composite parent, int styles) {
257 protected void delayedCreateControl(Composite parent, int styles) {
259 super.createControl(parent, styles);
261 Control control = getControl();
262 if (control instanceof Composite) {
263 Composite composite = (Composite) control;
264 composite.setLayout(new AdaptedRulerLayout(GAP_SIZE, this));
265 fOverviewRuler.createControl(composite, this);
269 private void ensureOverviewHoverManagerInstalled() {
270 if (fOverviewRulerHoveringController == null
271 && fAnnotationHover != null
272 && fHoverControlCreator != null) {
273 fOverviewRulerHoveringController =
274 new OverviewRulerHoverManager(
278 fHoverControlCreator);
279 fOverviewRulerHoveringController.install(fOverviewRuler.getControl());
283 public void hideOverviewRuler() {
284 fIsOverviewRulerVisible = false;
285 Control control = getControl();
286 if (control instanceof Composite) {
287 Composite composite = (Composite) control;
290 if (fOverviewRulerHoveringController != null) {
291 fOverviewRulerHoveringController.dispose();
292 fOverviewRulerHoveringController = null;
296 public void showOverviewRuler() {
297 fIsOverviewRulerVisible = true;
298 Control control = getControl();
299 if (control instanceof Composite) {
300 Composite composite = (Composite) control;
303 ensureOverviewHoverManagerInstalled();
306 public boolean isOverviewRulerVisible() {
307 return fIsOverviewRulerVisible;
311 * @see ISourceViewer#setDocument(IDocument, IAnnotationModel, int, int)
313 public void setDocument(
315 IAnnotationModel annotationModel,
316 int visibleRegionOffset,
317 int visibleRegionLength) {
322 visibleRegionLength);
323 fOverviewRuler.setModel(annotationModel);
326 // http://dev.eclipse.org/bugs/show_bug.cgi?id=19270
327 public void updateIndentationPrefixes() {
328 SourceViewerConfiguration configuration = getSourceViewerConfiguration();
329 String[] types = configuration.getConfiguredContentTypes(this);
330 for (int i = 0; i < types.length; i++) {
331 String[] prefixes = configuration.getIndentPrefixes(this, types[i]);
332 if (prefixes != null && prefixes.length > 0)
333 setIndentPrefixes(prefixes, types[i]);
338 * @see IWidgetTokenOwner#requestWidgetToken(IWidgetTokenKeeper)
340 public boolean requestWidgetToken(IWidgetTokenKeeper requester) {
341 if (WorkbenchHelp.isContextHelpDisplayed())
343 return super.requestWidgetToken(requester);
347 * @see org.eclipse.jface.text.source.ISourceViewer#configure(org.eclipse.jface.text.source.SourceViewerConfiguration)
349 public void configure(SourceViewerConfiguration configuration) {
350 super.configure(configuration);
351 // prependAutoEditStrategy(new SmartBracesAutoEditStrategy(this), IDocument.DEFAULT_CONTENT_TYPE);
354 protected void handleDispose() {
355 fOverviewRuler = null;
357 if (fOverviewRulerHoveringController != null) {
358 fOverviewRulerHoveringController.dispose();
359 fOverviewRulerHoveringController = null;
362 super.handleDispose();
367 static class TabConverter implements ITextConverter {
369 private int fTabRatio;
370 private ILineTracker fLineTracker;
372 public TabConverter() {
375 public void setNumberOfSpacesPerTab(int ratio) {
379 public void setLineTracker(ILineTracker lineTracker) {
380 fLineTracker = lineTracker;
383 private int insertTabString(StringBuffer buffer, int offsetInLine) {
388 int remainder = offsetInLine % fTabRatio;
389 remainder = fTabRatio - remainder;
390 for (int i = 0; i < remainder; i++)
395 public void customizeDocumentCommand(
397 DocumentCommand command) {
398 String text = command.text;
402 int index = text.indexOf('\t');
405 StringBuffer buffer = new StringBuffer();
407 fLineTracker.set(command.text);
408 int lines = fLineTracker.getNumberOfLines();
412 for (int i = 0; i < lines; i++) {
414 int offset = fLineTracker.getLineOffset(i);
415 int endOffset = offset + fLineTracker.getLineLength(i);
416 String line = text.substring(offset, endOffset);
421 document.getLineInformationOfOffset(command.offset);
422 position = command.offset - firstLine.getOffset();
425 int length = line.length();
426 for (int j = 0; j < length; j++) {
427 char c = line.charAt(j);
429 position += insertTabString(buffer, position);
438 command.text = buffer.toString();
440 } catch (BadLocationException x) {
446 private static class ExitPolicy implements LinkedPositionUI.ExitPolicy {
448 final char fExitCharacter;
450 public ExitPolicy(char exitCharacter) {
451 fExitCharacter= exitCharacter;
455 * @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)
457 public ExitFlags doExit(LinkedPositionManager manager, VerifyEvent event, int offset, int length) {
459 if (event.character == fExitCharacter) {
460 if (manager.anyPositionIncludes(offset, length))
461 return new ExitFlags(LinkedPositionUI.COMMIT| LinkedPositionUI.UPDATE_CARET, false);
463 return new ExitFlags(LinkedPositionUI.COMMIT, true);
466 switch (event.character) {
468 if (manager.getFirstPosition().length == 0)
469 return new ExitFlags(0, false);
475 return new ExitFlags(LinkedPositionUI.COMMIT, true);
483 private class BracketInserter implements VerifyKeyListener, LinkedPositionUI.ExitListener {
485 private boolean fCloseBrackets= true;
486 private boolean fCloseStrings= true;
491 public void setCloseBracketsEnabled(boolean enabled) {
492 fCloseBrackets= enabled;
495 public void setCloseStringsEnabled(boolean enabled) {
496 fCloseStrings= enabled;
499 private boolean hasIdentifierToTheRight(IDocument document, int offset) {
502 IRegion endLine= document.getLineInformationOfOffset(end);
503 int maxEnd= endLine.getOffset() + endLine.getLength();
504 while (end != maxEnd && Character.isWhitespace(document.getChar(end)))
507 return end != maxEnd && Character.isJavaIdentifierPart(document.getChar(end));
509 } catch (BadLocationException e) {
515 private boolean hasIdentifierToTheLeft(IDocument document, int offset) {
518 IRegion startLine= document.getLineInformationOfOffset(start);
519 int minStart= startLine.getOffset();
520 while (start != minStart && Character.isWhitespace(document.getChar(start - 1)))
523 return start != minStart && Character.isJavaIdentifierPart(document.getChar(start - 1));
525 } catch (BadLocationException e) {
530 private boolean hasCharacterToTheRight(IDocument document, int offset, char character) {
533 IRegion endLine= document.getLineInformationOfOffset(end);
534 int maxEnd= endLine.getOffset() + endLine.getLength();
535 while (end != maxEnd && Character.isWhitespace(document.getChar(end)))
538 return end != maxEnd && document.getChar(end) == character;
541 } catch (BadLocationException e) {
548 * @see org.eclipse.swt.custom.VerifyKeyListener#verifyKey(org.eclipse.swt.events.VerifyEvent)
550 public void verifyKey(VerifyEvent event) {
555 final ISourceViewer sourceViewer= getSourceViewer();
556 IDocument document= sourceViewer.getDocument();
558 final Point selection= sourceViewer.getSelectedRange();
559 final int offset= selection.x;
560 final int length= selection.y;
562 switch (event.character) {
564 if (hasCharacterToTheRight(document, offset + length, '('))
572 if (hasIdentifierToTheRight(document, offset + length))
578 if (event.character == '"') {
581 if (hasIdentifierToTheLeft(document, offset) || hasIdentifierToTheRight(document, offset + length))
586 ITypedRegion partition= document.getPartition(offset);
587 if (! IDocument.DEFAULT_CONTENT_TYPE.equals(partition.getType()) && partition.getOffset() != offset)
590 final char character= event.character;
591 final char closingCharacter= getPeerCharacter(character);
592 final StringBuffer buffer= new StringBuffer();
593 buffer.append(character);
594 buffer.append(closingCharacter);
596 document.replace(offset, length, buffer.toString());
598 LinkedPositionManager manager= new LinkedPositionManager(document);
599 manager.addPosition(offset + 1, 0);
604 LinkedPositionUI editor= new LinkedPositionUI(sourceViewer, manager);
605 editor.setCancelListener(this);
606 editor.setExitPolicy(new ExitPolicy(closingCharacter));
607 editor.setFinalCaretOffset(offset + 2);
610 IRegion newSelection= editor.getSelectedRegion();
611 sourceViewer.setSelectedRange(newSelection.getOffset(), newSelection.getLength());
615 } catch (BadLocationException e) {
622 * @see org.phpeclipse.phpdt.internal.ui.text.link.LinkedPositionUI.ExitListener#exit(boolean)
624 public void exit(boolean accept) {
630 final ISourceViewer sourceViewer= getSourceViewer();
631 IDocument document= sourceViewer.getDocument();
632 document.replace(fOffset, fLength, null);
633 } catch (BadLocationException e) {
638 /** The editor's paint manager */
639 private PaintManager fPaintManager;
640 /** The editor's bracket painter */
641 private BracketPainter fBracketPainter;
642 /** The editor's bracket matcher */
643 private PHPPairMatcher fBracketMatcher;
644 /** The editor's line painter */
645 private LinePainter fLinePainter;
646 /** The editor's print margin ruler painter */
647 private PrintMarginPainter fPrintMarginPainter;
648 /** The editor's problem painter */
649 private ProblemPainter fProblemPainter;
650 /** The editor's tab converter */
651 private TabConverter fTabConverter;
652 /** History for structure select action */
653 //private SelectionHistory fSelectionHistory;
655 /** The preference property change listener for php core. */
656 private IPropertyChangeListener fPropertyChangeListener= new PropertyChangeListener();
657 /** The remembered selection */
658 private ITextSelection fRememberedSelection;
659 /** The remembered php element offset */
660 private int fRememberedElementOffset;
661 /** The bracket inserter. */
662 private BracketInserter fBracketInserter= new BracketInserter();
664 private class PropertyChangeListener implements IPropertyChangeListener {
666 * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
668 public void propertyChange(org.eclipse.core.runtime.Preferences.PropertyChangeEvent event) {
669 handlePreferencePropertyChanged(event);
672 /* Preference key for code formatter tab size */
673 private final static String CODE_FORMATTER_TAB_SIZE =
674 PHPCore.FORMATTER_TAB_SIZE;
675 /** Preference key for matching brackets */
676 private final static String MATCHING_BRACKETS =
677 PreferenceConstants.EDITOR_MATCHING_BRACKETS;
678 /** Preference key for matching brackets color */
679 private final static String MATCHING_BRACKETS_COLOR =
680 PreferenceConstants.EDITOR_MATCHING_BRACKETS_COLOR;
681 /** Preference key for highlighting current line */
682 private final static String CURRENT_LINE =
683 PreferenceConstants.EDITOR_CURRENT_LINE;
684 /** Preference key for highlight color of current line */
685 private final static String CURRENT_LINE_COLOR =
686 PreferenceConstants.EDITOR_CURRENT_LINE_COLOR;
687 /** Preference key for showing print marging ruler */
688 private final static String PRINT_MARGIN =
689 PreferenceConstants.EDITOR_PRINT_MARGIN;
690 /** Preference key for print margin ruler color */
691 private final static String PRINT_MARGIN_COLOR =
692 PreferenceConstants.EDITOR_PRINT_MARGIN_COLOR;
693 /** Preference key for print margin ruler column */
694 private final static String PRINT_MARGIN_COLUMN =
695 PreferenceConstants.EDITOR_PRINT_MARGIN_COLUMN;
696 /** Preference key for inserting spaces rather than tabs */
697 private final static String SPACES_FOR_TABS =
698 PreferenceConstants.EDITOR_SPACES_FOR_TABS;
699 /** Preference key for error indication */
700 private final static String ERROR_INDICATION =
701 PreferenceConstants.EDITOR_PROBLEM_INDICATION;
702 /** Preference key for error color */
703 private final static String ERROR_INDICATION_COLOR =
704 PreferenceConstants.EDITOR_PROBLEM_INDICATION_COLOR;
705 /** Preference key for warning indication */
706 private final static String WARNING_INDICATION =
707 PreferenceConstants.EDITOR_WARNING_INDICATION;
708 /** Preference key for warning color */
709 private final static String WARNING_INDICATION_COLOR =
710 PreferenceConstants.EDITOR_WARNING_INDICATION_COLOR;
711 /** Preference key for task indication */
712 private final static String TASK_INDICATION =
713 PreferenceConstants.EDITOR_TASK_INDICATION;
714 /** Preference key for task color */
715 private final static String TASK_INDICATION_COLOR =
716 PreferenceConstants.EDITOR_TASK_INDICATION_COLOR;
717 /** Preference key for bookmark indication */
718 private final static String BOOKMARK_INDICATION =
719 PreferenceConstants.EDITOR_BOOKMARK_INDICATION;
720 /** Preference key for bookmark color */
721 private final static String BOOKMARK_INDICATION_COLOR =
722 PreferenceConstants.EDITOR_BOOKMARK_INDICATION_COLOR;
723 /** Preference key for search result indication */
724 private final static String SEARCH_RESULT_INDICATION =
725 PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION;
726 /** Preference key for search result color */
727 private final static String SEARCH_RESULT_INDICATION_COLOR =
728 PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION_COLOR;
729 /** Preference key for unknown annotation indication */
730 private final static String UNKNOWN_INDICATION =
731 PreferenceConstants.EDITOR_UNKNOWN_INDICATION;
732 /** Preference key for unknown annotation color */
733 private final static String UNKNOWN_INDICATION_COLOR =
734 PreferenceConstants.EDITOR_UNKNOWN_INDICATION_COLOR;
735 /** Preference key for linked position color */
736 private final static String LINKED_POSITION_COLOR =
737 PreferenceConstants.EDITOR_LINKED_POSITION_COLOR;
738 /** Preference key for shwoing the overview ruler */
739 private final static String OVERVIEW_RULER =
740 PreferenceConstants.EDITOR_OVERVIEW_RULER;
742 /** Preference key for error indication in overview ruler */
743 private final static String ERROR_INDICATION_IN_OVERVIEW_RULER =
744 PreferenceConstants.EDITOR_ERROR_INDICATION_IN_OVERVIEW_RULER;
745 /** Preference key for warning indication in overview ruler */
746 private final static String WARNING_INDICATION_IN_OVERVIEW_RULER =
747 PreferenceConstants.EDITOR_WARNING_INDICATION_IN_OVERVIEW_RULER;
748 /** Preference key for task indication in overview ruler */
749 private final static String TASK_INDICATION_IN_OVERVIEW_RULER =
750 PreferenceConstants.EDITOR_TASK_INDICATION_IN_OVERVIEW_RULER;
751 /** Preference key for bookmark indication in overview ruler */
752 private final static String BOOKMARK_INDICATION_IN_OVERVIEW_RULER =
753 PreferenceConstants.EDITOR_BOOKMARK_INDICATION_IN_OVERVIEW_RULER;
754 /** Preference key for search result indication in overview ruler */
755 private final static String SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER =
756 PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER;
757 /** Preference key for unknown annotation indication in overview ruler */
758 private final static String UNKNOWN_INDICATION_IN_OVERVIEW_RULER =
759 PreferenceConstants.EDITOR_UNKNOWN_INDICATION_IN_OVERVIEW_RULER;
760 /** Preference key for automatically closing strings */
761 private final static String CLOSE_STRINGS= PreferenceConstants.EDITOR_CLOSE_STRINGS;
762 /** Preference key for automatically wrapping Java strings */
763 private final static String WRAP_STRINGS= PreferenceConstants.EDITOR_WRAP_STRINGS;
764 /** Preference key for automatically closing brackets and parenthesis */
765 private final static String CLOSE_BRACKETS= PreferenceConstants.EDITOR_CLOSE_BRACKETS;
766 /** Preference key for automatically closing phpdocs and comments */
767 private final static String CLOSE_JAVADOCS= PreferenceConstants.EDITOR_CLOSE_JAVADOCS;
768 /** Preference key for automatically adding phpdoc tags */
769 private final static String ADD_JAVADOC_TAGS= PreferenceConstants.EDITOR_ADD_JAVADOC_TAGS;
770 /** Preference key for automatically formatting phpdocs */
771 private final static String FORMAT_JAVADOCS= PreferenceConstants.EDITOR_FORMAT_JAVADOCS;
772 /** Preference key for smart paste */
773 private final static String SMART_PASTE= PreferenceConstants.EDITOR_SMART_PASTE;
774 private final static class AnnotationInfo {
775 public String fColorPreference;
776 public String fOverviewRulerPreference;
777 public String fEditorPreference;
780 private final static Map ANNOTATION_MAP;
784 ANNOTATION_MAP = new HashMap();
786 info = new AnnotationInfo();
787 info.fColorPreference = TASK_INDICATION_COLOR;
788 info.fOverviewRulerPreference = TASK_INDICATION_IN_OVERVIEW_RULER;
789 info.fEditorPreference = TASK_INDICATION;
790 ANNOTATION_MAP.put(AnnotationType.TASK, info);
792 info = new AnnotationInfo();
793 info.fColorPreference = ERROR_INDICATION_COLOR;
794 info.fOverviewRulerPreference = ERROR_INDICATION_IN_OVERVIEW_RULER;
795 info.fEditorPreference = ERROR_INDICATION;
796 ANNOTATION_MAP.put(AnnotationType.ERROR, info);
798 info = new AnnotationInfo();
799 info.fColorPreference = WARNING_INDICATION_COLOR;
800 info.fOverviewRulerPreference = WARNING_INDICATION_IN_OVERVIEW_RULER;
801 info.fEditorPreference = WARNING_INDICATION;
802 ANNOTATION_MAP.put(AnnotationType.WARNING, info);
804 info = new AnnotationInfo();
805 info.fColorPreference = BOOKMARK_INDICATION_COLOR;
806 info.fOverviewRulerPreference = BOOKMARK_INDICATION_IN_OVERVIEW_RULER;
807 info.fEditorPreference = BOOKMARK_INDICATION;
808 ANNOTATION_MAP.put(AnnotationType.BOOKMARK, info);
810 info = new AnnotationInfo();
811 info.fColorPreference = SEARCH_RESULT_INDICATION_COLOR;
812 info.fOverviewRulerPreference = SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER;
813 info.fEditorPreference = SEARCH_RESULT_INDICATION;
814 ANNOTATION_MAP.put(AnnotationType.SEARCH_RESULT, info);
816 info = new AnnotationInfo();
817 info.fColorPreference = UNKNOWN_INDICATION_COLOR;
818 info.fOverviewRulerPreference = UNKNOWN_INDICATION_IN_OVERVIEW_RULER;
819 info.fEditorPreference = UNKNOWN_INDICATION;
820 ANNOTATION_MAP.put(AnnotationType.UNKNOWN, info);
823 private final static AnnotationType[] ANNOTATION_LAYERS =
824 new AnnotationType[] {
825 AnnotationType.UNKNOWN,
826 AnnotationType.BOOKMARK,
828 AnnotationType.SEARCH_RESULT,
829 AnnotationType.WARNING,
830 AnnotationType.ERROR };
833 * Creates a new php unit editor.
835 public PHPUnitEditor() {
837 setDocumentProvider(PHPeclipsePlugin.getDefault().getCompilationUnitDocumentProvider());
838 setEditorContextMenuId("#PHPEditorContext"); //$NON-NLS-1$
839 setRulerContextMenuId("#PHPRulerContext"); //$NON-NLS-1$
843 public void createPartControl(Composite parent) {
844 super.createPartControl(parent);
846 fPaintManager = new PaintManager(getSourceViewer());
848 LinePainter linePainter;
849 linePainter = new LinePainter(getSourceViewer());
851 linePainter.setHighlightColor(
852 new Color(Display.getCurrent(), 225, 235, 224));
854 fPaintManager.addPainter(linePainter);
857 if (isBracketHighlightingEnabled())
858 startBracketHighlighting();
859 if (isLineHighlightingEnabled())
860 startLineHighlighting();
861 if (isPrintMarginVisible())
865 Iterator e= ANNOTATION_MAP.keySet().iterator();
866 while (e.hasNext()) {
867 AnnotationType type= (AnnotationType) e.next();
868 if (isAnnotationIndicationEnabled(type))
869 startAnnotationIndication(type);
872 if (isTabConversionEnabled())
873 startTabConversion();
875 if (isOverviewRulerVisible())
879 Preferences preferences= PHPeclipsePlugin.getDefault().getPluginPreferences();
880 preferences.addPropertyChangeListener(fPropertyChangeListener);
882 IPreferenceStore preferenceStore= getPreferenceStore();
883 boolean closeBrackets= preferenceStore.getBoolean(CLOSE_BRACKETS);
884 boolean closeStrings= preferenceStore.getBoolean(CLOSE_STRINGS);
886 fBracketInserter.setCloseBracketsEnabled(closeBrackets);
887 fBracketInserter.setCloseStringsEnabled(closeStrings);
889 ISourceViewer sourceViewer= getSourceViewer();
890 if (sourceViewer instanceof ITextViewerExtension)
891 ((ITextViewerExtension) sourceViewer).prependVerifyKeyListener(fBracketInserter);
895 private static char getPeerCharacter(char character) {
913 throw new IllegalArgumentException();
918 * @see AbstractTextEditor#doSetInput(IEditorInput)
920 protected void doSetInput(IEditorInput input) throws CoreException {
921 super.doSetInput(input);
922 configureTabConverter();
925 private void startBracketHighlighting() {
926 if (fBracketPainter == null) {
927 ISourceViewer sourceViewer = getSourceViewer();
928 fBracketPainter = new BracketPainter(sourceViewer);
929 fBracketPainter.setHighlightColor(getColor(MATCHING_BRACKETS_COLOR));
930 fPaintManager.addPainter(fBracketPainter);
934 private void stopBracketHighlighting() {
935 if (fBracketPainter != null) {
936 fPaintManager.removePainter(fBracketPainter);
937 fBracketPainter.deactivate(true);
938 fBracketPainter.dispose();
939 fBracketPainter = null;
943 private boolean isBracketHighlightingEnabled() {
944 IPreferenceStore store = getPreferenceStore();
945 return store.getBoolean(MATCHING_BRACKETS);
948 private void startLineHighlighting() {
949 if (fLinePainter == null) {
950 ISourceViewer sourceViewer = getSourceViewer();
951 fLinePainter = new LinePainter(sourceViewer);
952 fLinePainter.setHighlightColor(getColor(CURRENT_LINE_COLOR));
953 fPaintManager.addPainter(fLinePainter);
957 private void stopLineHighlighting() {
958 if (fLinePainter != null) {
959 fPaintManager.removePainter(fLinePainter);
960 fLinePainter.deactivate(true);
961 fLinePainter.dispose();
966 private boolean isLineHighlightingEnabled() {
967 IPreferenceStore store = getPreferenceStore();
968 return store.getBoolean(CURRENT_LINE);
971 private void showPrintMargin() {
972 if (fPrintMarginPainter == null) {
973 fPrintMarginPainter = new PrintMarginPainter(getSourceViewer());
974 fPrintMarginPainter.setMarginRulerColor(getColor(PRINT_MARGIN_COLOR));
975 fPrintMarginPainter.setMarginRulerColumn(
976 getPreferenceStore().getInt(PRINT_MARGIN_COLUMN));
977 fPaintManager.addPainter(fPrintMarginPainter);
981 private void hidePrintMargin() {
982 if (fPrintMarginPainter != null) {
983 fPaintManager.removePainter(fPrintMarginPainter);
984 fPrintMarginPainter.deactivate(true);
985 fPrintMarginPainter.dispose();
986 fPrintMarginPainter = null;
990 private boolean isPrintMarginVisible() {
991 IPreferenceStore store = getPreferenceStore();
992 return store.getBoolean(PRINT_MARGIN);
995 private void startAnnotationIndication(AnnotationType annotationType) {
996 if (fProblemPainter == null) {
997 fProblemPainter = new ProblemPainter(this, getSourceViewer());
998 fPaintManager.addPainter(fProblemPainter);
1000 fProblemPainter.setColor(annotationType, getColor(annotationType));
1001 fProblemPainter.paintAnnotations(annotationType, true);
1002 fProblemPainter.paint(IPainter.CONFIGURATION);
1005 private void shutdownAnnotationIndication() {
1006 if (fProblemPainter != null) {
1008 if (!fProblemPainter.isPaintingAnnotations()) {
1009 fPaintManager.removePainter(fProblemPainter);
1010 fProblemPainter.deactivate(true);
1011 fProblemPainter.dispose();
1012 fProblemPainter = null;
1014 fProblemPainter.paint(IPainter.CONFIGURATION);
1019 private void stopAnnotationIndication(AnnotationType annotationType) {
1020 if (fProblemPainter != null) {
1021 fProblemPainter.paintAnnotations(annotationType, false);
1022 shutdownAnnotationIndication();
1026 private boolean isAnnotationIndicationEnabled(AnnotationType annotationType) {
1027 IPreferenceStore store = getPreferenceStore();
1028 AnnotationInfo info = (AnnotationInfo) ANNOTATION_MAP.get(annotationType);
1030 return store.getBoolean(info.fEditorPreference);
1034 private boolean isAnnotationIndicationInOverviewRulerEnabled(AnnotationType annotationType) {
1035 IPreferenceStore store = getPreferenceStore();
1036 AnnotationInfo info = (AnnotationInfo) ANNOTATION_MAP.get(annotationType);
1038 return store.getBoolean(info.fOverviewRulerPreference);
1042 private void showAnnotationIndicationInOverviewRuler(
1043 AnnotationType annotationType,
1045 AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
1046 OverviewRuler ruler = asv.getOverviewRuler();
1047 if (ruler != null) {
1048 ruler.setColor(annotationType, getColor(annotationType));
1049 ruler.showAnnotation(annotationType, show);
1054 private void setColorInOverviewRuler(
1055 AnnotationType annotationType,
1057 AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
1058 OverviewRuler ruler = asv.getOverviewRuler();
1059 if (ruler != null) {
1060 ruler.setColor(annotationType, color);
1065 private void configureTabConverter() {
1066 if (fTabConverter != null) {
1067 IDocumentProvider provider = getDocumentProvider();
1068 if (provider instanceof PHPDocumentProvider) {
1069 PHPDocumentProvider cup = (PHPDocumentProvider) provider;
1070 fTabConverter.setLineTracker(cup.createLineTracker(getEditorInput()));
1075 private int getTabSize() {
1076 Preferences preferences =
1077 PHPeclipsePlugin.getDefault().getPluginPreferences();
1078 return preferences.getInt(CODE_FORMATTER_TAB_SIZE);
1081 private void startTabConversion() {
1082 if (fTabConverter == null) {
1083 fTabConverter = new TabConverter();
1084 configureTabConverter();
1085 fTabConverter.setNumberOfSpacesPerTab(getTabSize());
1086 AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
1087 asv.addTextConverter(fTabConverter);
1088 // http://dev.eclipse.org/bugs/show_bug.cgi?id=19270
1089 asv.updateIndentationPrefixes();
1093 private void stopTabConversion() {
1094 if (fTabConverter != null) {
1095 AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
1096 asv.removeTextConverter(fTabConverter);
1097 // http://dev.eclipse.org/bugs/show_bug.cgi?id=19270
1098 asv.updateIndentationPrefixes();
1099 fTabConverter = null;
1103 private boolean isTabConversionEnabled() {
1104 IPreferenceStore store = getPreferenceStore();
1105 return store.getBoolean(SPACES_FOR_TABS);
1108 private void showOverviewRuler() {
1109 AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
1110 asv.showOverviewRuler();
1112 OverviewRuler overviewRuler = asv.getOverviewRuler();
1113 if (overviewRuler != null) {
1114 for (int i = 0; i < ANNOTATION_LAYERS.length; i++) {
1115 AnnotationType type = ANNOTATION_LAYERS[i];
1116 overviewRuler.setLayer(type, i);
1117 if (isAnnotationIndicationInOverviewRulerEnabled(type))
1118 showAnnotationIndicationInOverviewRuler(type, true);
1123 private void hideOverviewRuler() {
1124 AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
1125 asv.hideOverviewRuler();
1128 private boolean isOverviewRulerVisible() {
1129 IPreferenceStore store = getPreferenceStore();
1130 return store.getBoolean(OVERVIEW_RULER);
1133 private Color getColor(String key) {
1134 RGB rgb = PreferenceConverter.getColor(getPreferenceStore(), key);
1135 return getColor(rgb);
1138 private Color getColor(RGB rgb) {
1139 // JavaTextTools textTools = JavaPlugin.getDefault().getJavaTextTools();
1140 // return textTools.getColorManager().getColor(rgb);
1141 return PHPEditorEnvironment.getPHPColorProvider().getColor(rgb);
1144 private Color getColor(AnnotationType annotationType) {
1145 AnnotationInfo info = (AnnotationInfo) ANNOTATION_MAP.get(annotationType);
1147 return getColor(info.fColorPreference);
1151 public void dispose() {
1152 ISourceViewer sourceViewer= getSourceViewer();
1153 if (sourceViewer instanceof ITextViewerExtension)
1154 ((ITextViewerExtension) sourceViewer).removeVerifyKeyListener(fBracketInserter);
1156 if (fPropertyChangeListener != null) {
1157 Preferences preferences= PHPeclipsePlugin.getDefault().getPluginPreferences();
1158 preferences.removePropertyChangeListener(fPropertyChangeListener);
1159 fPropertyChangeListener= null;
1163 // if (fJavaEditorErrorTickUpdater != null) {
1164 // fJavaEditorErrorTickUpdater.dispose();
1165 // fJavaEditorErrorTickUpdater= null;
1168 // if (fSelectionHistory != null)
1169 // fSelectionHistory.dispose();
1171 if (fPaintManager != null) {
1172 fPaintManager.dispose();
1173 fPaintManager = null;
1176 if (fActionGroups != null)
1177 fActionGroups.dispose();
1182 protected AnnotationType getAnnotationType(String preferenceKey) {
1183 Iterator e= ANNOTATION_MAP.keySet().iterator();
1184 while (e.hasNext()) {
1185 AnnotationType type= (AnnotationType) e.next();
1186 AnnotationInfo info= (AnnotationInfo) ANNOTATION_MAP.get(type);
1188 if (preferenceKey.equals(info.fColorPreference) || preferenceKey.equals(info.fEditorPreference) || preferenceKey.equals(info.fOverviewRulerPreference))
1196 * @see AbstractTextEditor#handlePreferenceStoreChanged(PropertyChangeEvent)
1198 protected void handlePreferenceStoreChanged(PropertyChangeEvent event) {
1202 AdaptedSourceViewer asv= (AdaptedSourceViewer) getSourceViewer();
1205 String p= event.getProperty();
1207 if (CLOSE_BRACKETS.equals(p)) {
1208 fBracketInserter.setCloseBracketsEnabled(getPreferenceStore().getBoolean(p));
1212 if (CLOSE_STRINGS.equals(p)) {
1213 fBracketInserter.setCloseStringsEnabled(getPreferenceStore().getBoolean(p));
1217 if (SPACES_FOR_TABS.equals(p)) {
1218 if (isTabConversionEnabled())
1219 startTabConversion();
1221 stopTabConversion();
1225 if (MATCHING_BRACKETS.equals(p)) {
1226 if (isBracketHighlightingEnabled())
1227 startBracketHighlighting();
1229 stopBracketHighlighting();
1233 if (MATCHING_BRACKETS_COLOR.equals(p)) {
1234 if (fBracketPainter != null)
1235 fBracketPainter.setHighlightColor(getColor(MATCHING_BRACKETS_COLOR));
1239 if (CURRENT_LINE.equals(p)) {
1240 if (isLineHighlightingEnabled())
1241 startLineHighlighting();
1243 stopLineHighlighting();
1247 if (CURRENT_LINE_COLOR.equals(p)) {
1248 if (fLinePainter != null) {
1249 stopLineHighlighting();
1250 startLineHighlighting();
1255 if (PRINT_MARGIN.equals(p)) {
1256 if (isPrintMarginVisible())
1263 if (PRINT_MARGIN_COLOR.equals(p)) {
1264 if (fPrintMarginPainter != null)
1265 fPrintMarginPainter.setMarginRulerColor(getColor(PRINT_MARGIN_COLOR));
1269 if (PRINT_MARGIN_COLUMN.equals(p)) {
1270 if (fPrintMarginPainter != null)
1271 fPrintMarginPainter.setMarginRulerColumn(getPreferenceStore().getInt(PRINT_MARGIN_COLUMN));
1275 if (OVERVIEW_RULER.equals(p)) {
1276 if (isOverviewRulerVisible())
1277 showOverviewRuler();
1279 hideOverviewRuler();
1283 AnnotationType type= getAnnotationType(p);
1286 AnnotationInfo info= (AnnotationInfo) ANNOTATION_MAP.get(type);
1287 if (info.fColorPreference.equals(p)) {
1288 Color color= getColor(type);
1289 if (fProblemPainter != null) {
1290 fProblemPainter.setColor(type, color);
1291 fProblemPainter.paint(IPainter.CONFIGURATION);
1293 setColorInOverviewRuler(type, color);
1297 if (info.fEditorPreference.equals(p)) {
1298 if (isAnnotationIndicationEnabled(type))
1299 startAnnotationIndication(type);
1301 stopAnnotationIndication(type);
1305 if (info.fOverviewRulerPreference.equals(p)) {
1306 if (isAnnotationIndicationInOverviewRulerEnabled(type))
1307 showAnnotationIndicationInOverviewRuler(type, true);
1309 showAnnotationIndicationInOverviewRuler(type, false);
1314 // IContentAssistant c= asv.getContentAssistant();
1315 // if (c instanceof ContentAssistant)
1316 // ContentAssistPreference.changeConfiguration((ContentAssistant) c, getPreferenceStore(), event);
1320 super.handlePreferenceStoreChanged(event);
1325 * Handles a property change event describing a change
1326 * of the php core's preferences and updates the preference
1327 * related editor properties.
1329 * @param event the property change event
1331 protected void handlePreferencePropertyChanged(org.eclipse.core.runtime.Preferences.PropertyChangeEvent event) {
1332 AdaptedSourceViewer asv= (AdaptedSourceViewer) getSourceViewer();
1334 String p= event.getProperty();
1335 if (CODE_FORMATTER_TAB_SIZE.equals(p)) {
1336 asv.updateIndentationPrefixes();
1337 if (fTabConverter != null)
1338 fTabConverter.setNumberOfSpacesPerTab(getTabSize());
1344 * @see PHPEditor#createJavaSourceViewer(Composite, IVerticalRuler, int)
1346 protected ISourceViewer createJavaSourceViewer(Composite parent, IVerticalRuler ruler, int styles) {
1347 return new AdaptedSourceViewer(parent, ruler, styles);
1350 private boolean isValidSelection(int offset, int length) {
1351 IDocumentProvider provider= getDocumentProvider();
1352 if (provider != null) {
1353 IDocument document= provider.getDocument(getEditorInput());
1354 if (document != null) {
1355 int end= offset + length;
1356 int documentLength= document.getLength();
1357 return 0 <= offset && offset <= documentLength && 0 <= end && end <= documentLength;
1364 * @see AbstractTextEditor#canHandleMove(IEditorInput, IEditorInput)
1366 protected boolean canHandleMove(IEditorInput originalElement, IEditorInput movedElement) {
1368 String oldExtension= ""; //$NON-NLS-1$
1369 if (originalElement instanceof IFileEditorInput) {
1370 IFile file= ((IFileEditorInput) originalElement).getFile();
1372 String ext= file.getFileExtension();
1378 String newExtension= ""; //$NON-NLS-1$
1379 if (movedElement instanceof IFileEditorInput) {
1380 IFile file= ((IFileEditorInput) movedElement).getFile();
1382 newExtension= file.getFileExtension();
1385 return oldExtension.equals(newExtension);