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.link.LinkedPositionManager;
12 import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionUI;
13 import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionUI.ExitFlags;
14 import net.sourceforge.phpdt.ui.PreferenceConstants;
15 import net.sourceforge.phpdt.ui.text.JavaTextTools;
16 import net.sourceforge.phpeclipse.PHPCore;
17 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
19 import org.eclipse.core.resources.IFile;
20 import org.eclipse.core.runtime.CoreException;
21 import org.eclipse.core.runtime.Preferences;
22 import org.eclipse.core.runtime.Preferences.IPropertyChangeListener;
23 import org.eclipse.jface.preference.IPreferenceStore;
24 import org.eclipse.jface.preference.PreferenceConverter;
25 import org.eclipse.jface.text.AbstractHoverInformationControlManager;
26 import org.eclipse.jface.text.BadLocationException;
27 import org.eclipse.jface.text.DocumentCommand;
28 import org.eclipse.jface.text.IDocument;
29 import org.eclipse.jface.text.ILineTracker;
30 import org.eclipse.jface.text.IRegion;
31 import org.eclipse.jface.text.ITextSelection;
32 import org.eclipse.jface.text.ITextViewerExtension;
33 import org.eclipse.jface.text.ITypedRegion;
34 import org.eclipse.jface.text.IWidgetTokenKeeper;
35 import org.eclipse.jface.text.contentassist.ContentAssistant;
36 import org.eclipse.jface.text.contentassist.IContentAssistant;
37 import org.eclipse.jface.text.source.IAnnotationModel;
38 import org.eclipse.jface.text.source.ISourceViewer;
39 import org.eclipse.jface.text.source.IVerticalRuler;
40 import org.eclipse.jface.text.source.SourceViewer;
41 import org.eclipse.jface.text.source.SourceViewerConfiguration;
42 import org.eclipse.jface.util.PropertyChangeEvent;
43 import org.eclipse.swt.SWT;
44 import org.eclipse.swt.custom.StyledText;
45 import org.eclipse.swt.custom.VerifyKeyListener;
46 import org.eclipse.swt.events.VerifyEvent;
47 import org.eclipse.swt.graphics.Color;
48 import org.eclipse.swt.graphics.Point;
49 import org.eclipse.swt.graphics.RGB;
50 import org.eclipse.swt.graphics.Rectangle;
51 import org.eclipse.swt.widgets.Composite;
52 import org.eclipse.swt.widgets.Control;
53 import org.eclipse.swt.widgets.Display;
54 import org.eclipse.swt.widgets.Layout;
55 import org.eclipse.ui.IEditorInput;
56 import org.eclipse.ui.IFileEditorInput;
57 import org.eclipse.ui.help.WorkbenchHelp;
58 import org.eclipse.ui.texteditor.IDocumentProvider;
60 /**********************************************************************
61 Copyright (c) 2000, 2002 IBM Corp. and others.
62 All rights reserved. This program and the accompanying materials
63 are made available under the terms of the Common Public License v1.0
64 which accompanies this distribution, and is available at
65 http://www.eclipse.org/legal/cpl-v10.html
68 IBM Corporation - Initial implementation
69 Klaus Hartlage - www.eclipseproject.de
70 **********************************************************************/
72 * PHP specific text editor.
74 public class PHPUnitEditor extends PHPEditor {
75 interface ITextConverter {
76 void customizeDocumentCommand(IDocument document, DocumentCommand command);
79 class AdaptedRulerLayout extends Layout {
82 protected AdaptedSourceViewer fAdaptedSourceViewer;
84 protected AdaptedRulerLayout(int gap, AdaptedSourceViewer asv) {
86 fAdaptedSourceViewer = asv;
89 protected Point computeSize(
94 Control[] children = composite.getChildren();
96 children[children.length
97 - 1].computeSize(SWT.DEFAULT, SWT.DEFAULT, flushCache);
98 if (fAdaptedSourceViewer.isVerticalRulerVisible())
99 s.x += fAdaptedSourceViewer.getVerticalRuler().getWidth() + fGap;
103 protected void layout(Composite composite, boolean flushCache) {
104 Rectangle clArea = composite.getClientArea();
105 if (fAdaptedSourceViewer.isVerticalRulerVisible()) {
107 StyledText textWidget = fAdaptedSourceViewer.getTextWidget();
108 Rectangle trim = textWidget.computeTrim(0, 0, 0, 0);
109 int scrollbarHeight = trim.height;
111 IVerticalRuler vr = fAdaptedSourceViewer.getVerticalRuler();
112 int vrWidth = vr.getWidth();
115 if (fAdaptedSourceViewer.isOverviewRulerVisible()) {
116 OverviewRuler or = fAdaptedSourceViewer.getOverviewRuler();
117 orWidth = or.getWidth();
118 or.getControl().setBounds(
119 clArea.width - orWidth,
122 clArea.height - 3 * scrollbarHeight);
125 textWidget.setBounds(
128 clArea.width - vrWidth - orWidth - 2 * fGap,
130 vr.getControl().setBounds(
134 clArea.height - scrollbarHeight);
137 StyledText textWidget = fAdaptedSourceViewer.getTextWidget();
138 textWidget.setBounds(0, 0, clArea.width, clArea.height);
143 class AdaptedSourceViewer
144 extends SourceViewer { // extends JavaCorrectionSourceViewer {
146 private List fTextConverters;
148 private OverviewRuler fOverviewRuler;
149 private boolean fIsOverviewRulerVisible;
150 /** The viewer's overview ruler hovering controller */
151 private AbstractHoverInformationControlManager fOverviewRulerHoveringController;
153 private boolean fIgnoreTextConverters = false;
155 private IVerticalRuler fCachedVerticalRuler;
156 private boolean fCachedIsVerticalRulerVisible;
158 public AdaptedSourceViewer(
160 IVerticalRuler ruler,
162 super(parent, ruler, styles); //, CompilationUnitEditor.this);
164 fCachedVerticalRuler = ruler;
165 fCachedIsVerticalRulerVisible = (ruler != null);
166 fOverviewRuler = new OverviewRuler(VERTICAL_RULER_WIDTH);
168 delayedCreateControl(parent, styles);
172 * @see ISourceViewer#showAnnotations(boolean)
174 public void showAnnotations(boolean show) {
175 fCachedIsVerticalRulerVisible = (show && fCachedVerticalRuler != null);
176 // super.showAnnotations(show);
179 public IContentAssistant getContentAssistant() {
180 return fContentAssistant;
184 * @see ITextOperationTarget#doOperation(int)
186 public void doOperation(int operation) {
188 if (getTextWidget() == null)
192 case CONTENTASSIST_PROPOSALS :
193 String msg = fContentAssistant.showPossibleCompletions();
194 setStatusLineErrorMessage(msg);
197 fIgnoreTextConverters = true;
200 fIgnoreTextConverters = true;
204 super.doOperation(operation);
207 public void insertTextConverter(ITextConverter textConverter, int index) {
208 throw new UnsupportedOperationException();
211 public void addTextConverter(ITextConverter textConverter) {
212 if (fTextConverters == null) {
213 fTextConverters = new ArrayList(1);
214 fTextConverters.add(textConverter);
215 } else if (!fTextConverters.contains(textConverter))
216 fTextConverters.add(textConverter);
219 public void removeTextConverter(ITextConverter textConverter) {
220 if (fTextConverters != null) {
221 fTextConverters.remove(textConverter);
222 if (fTextConverters.size() == 0)
223 fTextConverters = null;
228 * @see TextViewer#customizeDocumentCommand(DocumentCommand)
230 protected void customizeDocumentCommand(DocumentCommand command) {
231 super.customizeDocumentCommand(command);
232 if (!fIgnoreTextConverters && fTextConverters != null) {
233 for (Iterator e = fTextConverters.iterator(); e.hasNext();)
234 ((ITextConverter) e.next()).customizeDocumentCommand(
238 fIgnoreTextConverters = false;
241 public IVerticalRuler getVerticalRuler() {
242 return fCachedVerticalRuler;
245 public boolean isVerticalRulerVisible() {
246 return fCachedIsVerticalRulerVisible;
249 public OverviewRuler getOverviewRuler() {
250 return fOverviewRuler;
254 * @see TextViewer#createControl(Composite, int)
256 protected void createControl(Composite parent, int styles) {
260 protected void delayedCreateControl(Composite parent, int styles) {
262 super.createControl(parent, styles);
264 Control control = getControl();
265 if (control instanceof Composite) {
266 Composite composite = (Composite) control;
267 composite.setLayout(new AdaptedRulerLayout(GAP_SIZE, this));
268 fOverviewRuler.createControl(composite, this);
272 protected void ensureOverviewHoverManagerInstalled() {
273 if (fOverviewRulerHoveringController == null
274 && fAnnotationHover != null
275 && fHoverControlCreator != null) {
276 fOverviewRulerHoveringController =
277 new OverviewRulerHoverManager(
281 fHoverControlCreator);
282 fOverviewRulerHoveringController.install(fOverviewRuler.getControl());
286 public void hideOverviewRuler() {
287 fIsOverviewRulerVisible = false;
288 Control control = getControl();
289 if (control instanceof Composite) {
290 Composite composite = (Composite) control;
293 if (fOverviewRulerHoveringController != null) {
294 fOverviewRulerHoveringController.dispose();
295 fOverviewRulerHoveringController = null;
299 public void showOverviewRuler() {
300 fIsOverviewRulerVisible = true;
301 Control control = getControl();
302 if (control instanceof Composite) {
303 Composite composite = (Composite) control;
306 ensureOverviewHoverManagerInstalled();
309 public boolean isOverviewRulerVisible() {
310 return fIsOverviewRulerVisible;
314 * @see ISourceViewer#setDocument(IDocument, IAnnotationModel, int, int)
316 public void setDocument(
318 IAnnotationModel annotationModel,
319 int visibleRegionOffset,
320 int visibleRegionLength) {
325 visibleRegionLength);
326 fOverviewRuler.setModel(annotationModel);
329 // http://dev.eclipse.org/bugs/show_bug.cgi?id=19270
330 public void updateIndentationPrefixes() {
331 SourceViewerConfiguration configuration = getSourceViewerConfiguration();
332 String[] types = configuration.getConfiguredContentTypes(this);
333 for (int i = 0; i < types.length; i++) {
334 String[] prefixes = configuration.getIndentPrefixes(this, types[i]);
335 if (prefixes != null && prefixes.length > 0)
336 setIndentPrefixes(prefixes, types[i]);
341 * @see IWidgetTokenOwner#requestWidgetToken(IWidgetTokenKeeper)
343 public boolean requestWidgetToken(IWidgetTokenKeeper requester) {
344 if (WorkbenchHelp.isContextHelpDisplayed())
346 return super.requestWidgetToken(requester);
350 * @see org.eclipse.jface.text.source.ISourceViewer#configure(org.eclipse.jface.text.source.SourceViewerConfiguration)
352 public void configure(SourceViewerConfiguration configuration) {
353 super.configure(configuration);
354 // prependAutoEditStrategy(new SmartBracesAutoEditStrategy(this), IDocument.DEFAULT_CONTENT_TYPE);
357 protected void handleDispose() {
358 fOverviewRuler = null;
360 if (fOverviewRulerHoveringController != null) {
361 fOverviewRulerHoveringController.dispose();
362 fOverviewRulerHoveringController = null;
365 super.handleDispose();
370 static class TabConverter implements ITextConverter {
372 private int fTabRatio;
373 private ILineTracker fLineTracker;
375 public TabConverter() {
378 public void setNumberOfSpacesPerTab(int ratio) {
382 public void setLineTracker(ILineTracker lineTracker) {
383 fLineTracker = lineTracker;
386 private int insertTabString(StringBuffer buffer, int offsetInLine) {
391 int remainder = offsetInLine % fTabRatio;
392 remainder = fTabRatio - remainder;
393 for (int i = 0; i < remainder; i++)
398 public void customizeDocumentCommand(
400 DocumentCommand command) {
401 String text = command.text;
405 int index = text.indexOf('\t');
408 StringBuffer buffer = new StringBuffer();
410 fLineTracker.set(command.text);
411 int lines = fLineTracker.getNumberOfLines();
415 for (int i = 0; i < lines; i++) {
417 int offset = fLineTracker.getLineOffset(i);
418 int endOffset = offset + fLineTracker.getLineLength(i);
419 String line = text.substring(offset, endOffset);
424 document.getLineInformationOfOffset(command.offset);
425 position = command.offset - firstLine.getOffset();
428 int length = line.length();
429 for (int j = 0; j < length; j++) {
430 char c = line.charAt(j);
432 position += insertTabString(buffer, position);
441 command.text = buffer.toString();
443 } catch (BadLocationException x) {
449 private static class ExitPolicy implements LinkedPositionUI.ExitPolicy {
451 final char fExitCharacter;
453 public ExitPolicy(char exitCharacter) {
454 fExitCharacter= exitCharacter;
458 * @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)
460 public ExitFlags doExit(LinkedPositionManager manager, VerifyEvent event, int offset, int length) {
462 if (event.character == fExitCharacter) {
463 if (manager.anyPositionIncludes(offset, length))
464 return new ExitFlags(LinkedPositionUI.COMMIT| LinkedPositionUI.UPDATE_CARET, false);
466 return new ExitFlags(LinkedPositionUI.COMMIT, true);
469 switch (event.character) {
471 if (manager.getFirstPosition().length == 0)
472 return new ExitFlags(0, false);
478 return new ExitFlags(LinkedPositionUI.COMMIT, true);
486 private class BracketInserter implements VerifyKeyListener, LinkedPositionUI.ExitListener {
488 private boolean fCloseBrackets= true;
489 private boolean fCloseStrings= true;
494 public void setCloseBracketsEnabled(boolean enabled) {
495 fCloseBrackets= enabled;
498 public void setCloseStringsEnabled(boolean enabled) {
499 fCloseStrings= enabled;
502 private boolean hasIdentifierToTheRight(IDocument document, int offset) {
505 IRegion endLine= document.getLineInformationOfOffset(end);
506 int maxEnd= endLine.getOffset() + endLine.getLength();
507 while (end != maxEnd && Character.isWhitespace(document.getChar(end)))
510 return end != maxEnd && Character.isJavaIdentifierPart(document.getChar(end));
512 } catch (BadLocationException e) {
518 private boolean hasIdentifierToTheLeft(IDocument document, int offset) {
521 IRegion startLine= document.getLineInformationOfOffset(start);
522 int minStart= startLine.getOffset();
523 while (start != minStart && Character.isWhitespace(document.getChar(start - 1)))
526 return start != minStart && Character.isJavaIdentifierPart(document.getChar(start - 1));
528 } catch (BadLocationException e) {
533 private boolean hasCharacterToTheRight(IDocument document, int offset, char character) {
536 IRegion endLine= document.getLineInformationOfOffset(end);
537 int maxEnd= endLine.getOffset() + endLine.getLength();
538 while (end != maxEnd && Character.isWhitespace(document.getChar(end)))
541 return end != maxEnd && document.getChar(end) == character;
544 } catch (BadLocationException e) {
551 * @see org.eclipse.swt.custom.VerifyKeyListener#verifyKey(org.eclipse.swt.events.VerifyEvent)
553 public void verifyKey(VerifyEvent event) {
558 final ISourceViewer sourceViewer= getSourceViewer();
559 IDocument document= sourceViewer.getDocument();
561 final Point selection= sourceViewer.getSelectedRange();
562 final int offset= selection.x;
563 final int length= selection.y;
565 switch (event.character) {
567 if (hasCharacterToTheRight(document, offset + length, '('))
575 if (hasIdentifierToTheRight(document, offset + length))
581 if (event.character == '"') {
584 if (hasIdentifierToTheLeft(document, offset) || hasIdentifierToTheRight(document, offset + length))
589 ITypedRegion partition= document.getPartition(offset);
590 if (! IDocument.DEFAULT_CONTENT_TYPE.equals(partition.getType()) && partition.getOffset() != offset)
593 final char character= event.character;
594 final char closingCharacter= getPeerCharacter(character);
595 final StringBuffer buffer= new StringBuffer();
596 buffer.append(character);
597 buffer.append(closingCharacter);
599 document.replace(offset, length, buffer.toString());
601 LinkedPositionManager manager= new LinkedPositionManager(document);
602 manager.addPosition(offset + 1, 0);
607 LinkedPositionUI editor= new LinkedPositionUI(sourceViewer, manager);
608 editor.setCancelListener(this);
609 editor.setExitPolicy(new ExitPolicy(closingCharacter));
610 editor.setFinalCaretOffset(offset + 2);
613 IRegion newSelection= editor.getSelectedRegion();
614 sourceViewer.setSelectedRange(newSelection.getOffset(), newSelection.getLength());
618 } catch (BadLocationException e) {
625 * @see org.phpeclipse.phpdt.internal.ui.text.link.LinkedPositionUI.ExitListener#exit(boolean)
627 public void exit(boolean accept) {
633 final ISourceViewer sourceViewer= getSourceViewer();
634 IDocument document= sourceViewer.getDocument();
635 document.replace(fOffset, fLength, null);
636 } catch (BadLocationException e) {
641 /** The editor's paint manager */
642 private PaintManager fPaintManager;
643 /** The editor's bracket painter */
644 private BracketPainter fBracketPainter;
645 /** The editor's bracket matcher */
646 private PHPPairMatcher fBracketMatcher;
647 /** The editor's line painter */
648 private LinePainter fLinePainter;
649 /** The editor's print margin ruler painter */
650 private PrintMarginPainter fPrintMarginPainter;
651 /** The editor's problem painter */
652 private ProblemPainter fProblemPainter;
653 /** The editor's tab converter */
654 private TabConverter fTabConverter;
655 /** History for structure select action */
656 //private SelectionHistory fSelectionHistory;
658 /** The preference property change listener for php core. */
659 private IPropertyChangeListener fPropertyChangeListener= new PropertyChangeListener();
660 /** The remembered selection */
661 private ITextSelection fRememberedSelection;
662 /** The remembered php element offset */
663 private int fRememberedElementOffset;
664 /** The bracket inserter. */
665 private BracketInserter fBracketInserter= new BracketInserter();
667 private class PropertyChangeListener implements IPropertyChangeListener {
669 * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
671 public void propertyChange(org.eclipse.core.runtime.Preferences.PropertyChangeEvent event) {
672 handlePreferencePropertyChanged(event);
675 /* Preference key for code formatter tab size */
676 private final static String CODE_FORMATTER_TAB_SIZE =
677 PHPCore.FORMATTER_TAB_SIZE;
678 /** Preference key for matching brackets */
679 private final static String MATCHING_BRACKETS =
680 PreferenceConstants.EDITOR_MATCHING_BRACKETS;
681 /** Preference key for matching brackets color */
682 private final static String MATCHING_BRACKETS_COLOR =
683 PreferenceConstants.EDITOR_MATCHING_BRACKETS_COLOR;
684 /** Preference key for highlighting current line */
685 private final static String CURRENT_LINE =
686 PreferenceConstants.EDITOR_CURRENT_LINE;
687 /** Preference key for highlight color of current line */
688 private final static String CURRENT_LINE_COLOR =
689 PreferenceConstants.EDITOR_CURRENT_LINE_COLOR;
690 /** Preference key for showing print marging ruler */
691 private final static String PRINT_MARGIN =
692 PreferenceConstants.EDITOR_PRINT_MARGIN;
693 /** Preference key for print margin ruler color */
694 private final static String PRINT_MARGIN_COLOR =
695 PreferenceConstants.EDITOR_PRINT_MARGIN_COLOR;
696 /** Preference key for print margin ruler column */
697 private final static String PRINT_MARGIN_COLUMN =
698 PreferenceConstants.EDITOR_PRINT_MARGIN_COLUMN;
699 /** Preference key for inserting spaces rather than tabs */
700 private final static String SPACES_FOR_TABS =
701 PreferenceConstants.EDITOR_SPACES_FOR_TABS;
702 /** Preference key for error indication */
703 private final static String ERROR_INDICATION =
704 PreferenceConstants.EDITOR_PROBLEM_INDICATION;
705 /** Preference key for error color */
706 private final static String ERROR_INDICATION_COLOR =
707 PreferenceConstants.EDITOR_PROBLEM_INDICATION_COLOR;
708 /** Preference key for warning indication */
709 private final static String WARNING_INDICATION =
710 PreferenceConstants.EDITOR_WARNING_INDICATION;
711 /** Preference key for warning color */
712 private final static String WARNING_INDICATION_COLOR =
713 PreferenceConstants.EDITOR_WARNING_INDICATION_COLOR;
714 /** Preference key for task indication */
715 private final static String TASK_INDICATION =
716 PreferenceConstants.EDITOR_TASK_INDICATION;
717 /** Preference key for task color */
718 private final static String TASK_INDICATION_COLOR =
719 PreferenceConstants.EDITOR_TASK_INDICATION_COLOR;
720 /** Preference key for bookmark indication */
721 private final static String BOOKMARK_INDICATION =
722 PreferenceConstants.EDITOR_BOOKMARK_INDICATION;
723 /** Preference key for bookmark color */
724 private final static String BOOKMARK_INDICATION_COLOR =
725 PreferenceConstants.EDITOR_BOOKMARK_INDICATION_COLOR;
726 /** Preference key for search result indication */
727 private final static String SEARCH_RESULT_INDICATION =
728 PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION;
729 /** Preference key for search result color */
730 private final static String SEARCH_RESULT_INDICATION_COLOR =
731 PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION_COLOR;
732 /** Preference key for unknown annotation indication */
733 private final static String UNKNOWN_INDICATION =
734 PreferenceConstants.EDITOR_UNKNOWN_INDICATION;
735 /** Preference key for unknown annotation color */
736 private final static String UNKNOWN_INDICATION_COLOR =
737 PreferenceConstants.EDITOR_UNKNOWN_INDICATION_COLOR;
738 /** Preference key for linked position color */
739 private final static String LINKED_POSITION_COLOR =
740 PreferenceConstants.EDITOR_LINKED_POSITION_COLOR;
741 /** Preference key for shwoing the overview ruler */
742 private final static String OVERVIEW_RULER =
743 PreferenceConstants.EDITOR_OVERVIEW_RULER;
745 /** Preference key for error indication in overview ruler */
746 private final static String ERROR_INDICATION_IN_OVERVIEW_RULER =
747 PreferenceConstants.EDITOR_ERROR_INDICATION_IN_OVERVIEW_RULER;
748 /** Preference key for warning indication in overview ruler */
749 private final static String WARNING_INDICATION_IN_OVERVIEW_RULER =
750 PreferenceConstants.EDITOR_WARNING_INDICATION_IN_OVERVIEW_RULER;
751 /** Preference key for task indication in overview ruler */
752 private final static String TASK_INDICATION_IN_OVERVIEW_RULER =
753 PreferenceConstants.EDITOR_TASK_INDICATION_IN_OVERVIEW_RULER;
754 /** Preference key for bookmark indication in overview ruler */
755 private final static String BOOKMARK_INDICATION_IN_OVERVIEW_RULER =
756 PreferenceConstants.EDITOR_BOOKMARK_INDICATION_IN_OVERVIEW_RULER;
757 /** Preference key for search result indication in overview ruler */
758 private final static String SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER =
759 PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER;
760 /** Preference key for unknown annotation indication in overview ruler */
761 private final static String UNKNOWN_INDICATION_IN_OVERVIEW_RULER =
762 PreferenceConstants.EDITOR_UNKNOWN_INDICATION_IN_OVERVIEW_RULER;
763 /** Preference key for automatically closing strings */
764 private final static String CLOSE_STRINGS= PreferenceConstants.EDITOR_CLOSE_STRINGS;
765 /** Preference key for automatically wrapping Java strings */
766 private final static String WRAP_STRINGS= PreferenceConstants.EDITOR_WRAP_STRINGS;
767 /** Preference key for automatically closing brackets and parenthesis */
768 private final static String CLOSE_BRACKETS= PreferenceConstants.EDITOR_CLOSE_BRACKETS;
769 /** Preference key for automatically closing phpdocs and comments */
770 private final static String CLOSE_JAVADOCS= PreferenceConstants.EDITOR_CLOSE_JAVADOCS;
771 /** Preference key for automatically adding phpdoc tags */
772 private final static String ADD_JAVADOC_TAGS= PreferenceConstants.EDITOR_ADD_JAVADOC_TAGS;
773 /** Preference key for automatically formatting phpdocs */
774 private final static String FORMAT_JAVADOCS= PreferenceConstants.EDITOR_FORMAT_JAVADOCS;
775 /** Preference key for smart paste */
776 private final static String SMART_PASTE= PreferenceConstants.EDITOR_SMART_PASTE;
777 private final static class AnnotationInfo {
778 public String fColorPreference;
779 public String fOverviewRulerPreference;
780 public String fEditorPreference;
783 private final static Map ANNOTATION_MAP;
787 ANNOTATION_MAP = new HashMap();
789 info = new AnnotationInfo();
790 info.fColorPreference = TASK_INDICATION_COLOR;
791 info.fOverviewRulerPreference = TASK_INDICATION_IN_OVERVIEW_RULER;
792 info.fEditorPreference = TASK_INDICATION;
793 ANNOTATION_MAP.put(AnnotationType.TASK, info);
795 info = new AnnotationInfo();
796 info.fColorPreference = ERROR_INDICATION_COLOR;
797 info.fOverviewRulerPreference = ERROR_INDICATION_IN_OVERVIEW_RULER;
798 info.fEditorPreference = ERROR_INDICATION;
799 ANNOTATION_MAP.put(AnnotationType.ERROR, info);
801 info = new AnnotationInfo();
802 info.fColorPreference = WARNING_INDICATION_COLOR;
803 info.fOverviewRulerPreference = WARNING_INDICATION_IN_OVERVIEW_RULER;
804 info.fEditorPreference = WARNING_INDICATION;
805 ANNOTATION_MAP.put(AnnotationType.WARNING, info);
807 info = new AnnotationInfo();
808 info.fColorPreference = BOOKMARK_INDICATION_COLOR;
809 info.fOverviewRulerPreference = BOOKMARK_INDICATION_IN_OVERVIEW_RULER;
810 info.fEditorPreference = BOOKMARK_INDICATION;
811 ANNOTATION_MAP.put(AnnotationType.BOOKMARK, info);
813 info = new AnnotationInfo();
814 info.fColorPreference = SEARCH_RESULT_INDICATION_COLOR;
815 info.fOverviewRulerPreference = SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER;
816 info.fEditorPreference = SEARCH_RESULT_INDICATION;
817 ANNOTATION_MAP.put(AnnotationType.SEARCH_RESULT, info);
819 info = new AnnotationInfo();
820 info.fColorPreference = UNKNOWN_INDICATION_COLOR;
821 info.fOverviewRulerPreference = UNKNOWN_INDICATION_IN_OVERVIEW_RULER;
822 info.fEditorPreference = UNKNOWN_INDICATION;
823 ANNOTATION_MAP.put(AnnotationType.UNKNOWN, info);
826 private final static AnnotationType[] ANNOTATION_LAYERS =
827 new AnnotationType[] {
828 AnnotationType.UNKNOWN,
829 AnnotationType.BOOKMARK,
831 AnnotationType.SEARCH_RESULT,
832 AnnotationType.WARNING,
833 AnnotationType.ERROR };
836 * Creates a new php unit editor.
838 public PHPUnitEditor() {
840 setDocumentProvider(PHPeclipsePlugin.getDefault().getCompilationUnitDocumentProvider());
841 setEditorContextMenuId("#PHPEditorContext"); //$NON-NLS-1$
842 setRulerContextMenuId("#PHPRulerContext"); //$NON-NLS-1$
846 public void createPartControl(Composite parent) {
847 super.createPartControl(parent);
849 fPaintManager = new PaintManager(getSourceViewer());
851 LinePainter linePainter;
852 linePainter = new LinePainter(getSourceViewer());
854 linePainter.setHighlightColor(
855 new Color(Display.getCurrent(), 225, 235, 224));
857 fPaintManager.addPainter(linePainter);
860 if (isBracketHighlightingEnabled())
861 startBracketHighlighting();
862 if (isLineHighlightingEnabled())
863 startLineHighlighting();
864 if (isPrintMarginVisible())
868 Iterator e= ANNOTATION_MAP.keySet().iterator();
869 while (e.hasNext()) {
870 AnnotationType type= (AnnotationType) e.next();
871 if (isAnnotationIndicationEnabled(type))
872 startAnnotationIndication(type);
875 if (isTabConversionEnabled())
876 startTabConversion();
878 if (isOverviewRulerVisible())
882 Preferences preferences= PHPeclipsePlugin.getDefault().getPluginPreferences();
883 preferences.addPropertyChangeListener(fPropertyChangeListener);
885 IPreferenceStore preferenceStore= getPreferenceStore();
886 boolean closeBrackets= preferenceStore.getBoolean(CLOSE_BRACKETS);
887 boolean closeStrings= preferenceStore.getBoolean(CLOSE_STRINGS);
889 fBracketInserter.setCloseBracketsEnabled(closeBrackets);
890 fBracketInserter.setCloseStringsEnabled(closeStrings);
892 ISourceViewer sourceViewer= getSourceViewer();
893 if (sourceViewer instanceof ITextViewerExtension)
894 ((ITextViewerExtension) sourceViewer).prependVerifyKeyListener(fBracketInserter);
898 private static char getPeerCharacter(char character) {
916 throw new IllegalArgumentException();
921 * @see AbstractTextEditor#doSetInput(IEditorInput)
923 protected void doSetInput(IEditorInput input) throws CoreException {
924 super.doSetInput(input);
925 configureTabConverter();
928 private void startBracketHighlighting() {
929 if (fBracketPainter == null) {
930 ISourceViewer sourceViewer = getSourceViewer();
931 fBracketPainter = new BracketPainter(sourceViewer);
932 fBracketPainter.setHighlightColor(getColor(MATCHING_BRACKETS_COLOR));
933 fPaintManager.addPainter(fBracketPainter);
937 private void stopBracketHighlighting() {
938 if (fBracketPainter != null) {
939 fPaintManager.removePainter(fBracketPainter);
940 fBracketPainter.deactivate(true);
941 fBracketPainter.dispose();
942 fBracketPainter = null;
946 private boolean isBracketHighlightingEnabled() {
947 IPreferenceStore store = getPreferenceStore();
948 return store.getBoolean(MATCHING_BRACKETS);
951 private void startLineHighlighting() {
952 if (fLinePainter == null) {
953 ISourceViewer sourceViewer = getSourceViewer();
954 fLinePainter = new LinePainter(sourceViewer);
955 fLinePainter.setHighlightColor(getColor(CURRENT_LINE_COLOR));
956 fPaintManager.addPainter(fLinePainter);
960 private void stopLineHighlighting() {
961 if (fLinePainter != null) {
962 fPaintManager.removePainter(fLinePainter);
963 fLinePainter.deactivate(true);
964 fLinePainter.dispose();
969 private boolean isLineHighlightingEnabled() {
970 IPreferenceStore store = getPreferenceStore();
971 return store.getBoolean(CURRENT_LINE);
974 private void showPrintMargin() {
975 if (fPrintMarginPainter == null) {
976 fPrintMarginPainter = new PrintMarginPainter(getSourceViewer());
977 fPrintMarginPainter.setMarginRulerColor(getColor(PRINT_MARGIN_COLOR));
978 fPrintMarginPainter.setMarginRulerColumn(
979 getPreferenceStore().getInt(PRINT_MARGIN_COLUMN));
980 fPaintManager.addPainter(fPrintMarginPainter);
984 private void hidePrintMargin() {
985 if (fPrintMarginPainter != null) {
986 fPaintManager.removePainter(fPrintMarginPainter);
987 fPrintMarginPainter.deactivate(true);
988 fPrintMarginPainter.dispose();
989 fPrintMarginPainter = null;
993 private boolean isPrintMarginVisible() {
994 IPreferenceStore store = getPreferenceStore();
995 return store.getBoolean(PRINT_MARGIN);
998 private void startAnnotationIndication(AnnotationType annotationType) {
999 if (fProblemPainter == null) {
1000 fProblemPainter = new ProblemPainter(this, getSourceViewer());
1001 fPaintManager.addPainter(fProblemPainter);
1003 fProblemPainter.setColor(annotationType, getColor(annotationType));
1004 fProblemPainter.paintAnnotations(annotationType, true);
1005 fProblemPainter.paint(IPainter.CONFIGURATION);
1008 private void shutdownAnnotationIndication() {
1009 if (fProblemPainter != null) {
1011 if (!fProblemPainter.isPaintingAnnotations()) {
1012 fPaintManager.removePainter(fProblemPainter);
1013 fProblemPainter.deactivate(true);
1014 fProblemPainter.dispose();
1015 fProblemPainter = null;
1017 fProblemPainter.paint(IPainter.CONFIGURATION);
1022 private void stopAnnotationIndication(AnnotationType annotationType) {
1023 if (fProblemPainter != null) {
1024 fProblemPainter.paintAnnotations(annotationType, false);
1025 shutdownAnnotationIndication();
1029 private boolean isAnnotationIndicationEnabled(AnnotationType annotationType) {
1030 IPreferenceStore store = getPreferenceStore();
1031 AnnotationInfo info = (AnnotationInfo) ANNOTATION_MAP.get(annotationType);
1033 return store.getBoolean(info.fEditorPreference);
1037 private boolean isAnnotationIndicationInOverviewRulerEnabled(AnnotationType annotationType) {
1038 IPreferenceStore store = getPreferenceStore();
1039 AnnotationInfo info = (AnnotationInfo) ANNOTATION_MAP.get(annotationType);
1041 return store.getBoolean(info.fOverviewRulerPreference);
1045 private void showAnnotationIndicationInOverviewRuler(
1046 AnnotationType annotationType,
1048 AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
1049 OverviewRuler ruler = asv.getOverviewRuler();
1050 if (ruler != null) {
1051 ruler.setColor(annotationType, getColor(annotationType));
1052 ruler.showAnnotation(annotationType, show);
1057 private void setColorInOverviewRuler(
1058 AnnotationType annotationType,
1060 AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
1061 OverviewRuler ruler = asv.getOverviewRuler();
1062 if (ruler != null) {
1063 ruler.setColor(annotationType, color);
1068 private void configureTabConverter() {
1069 if (fTabConverter != null) {
1070 IDocumentProvider provider = getDocumentProvider();
1071 if (provider instanceof PHPDocumentProvider) {
1072 PHPDocumentProvider cup = (PHPDocumentProvider) provider;
1073 fTabConverter.setLineTracker(cup.createLineTracker(getEditorInput()));
1078 private int getTabSize() {
1079 Preferences preferences =
1080 PHPeclipsePlugin.getDefault().getPluginPreferences();
1081 return preferences.getInt(CODE_FORMATTER_TAB_SIZE);
1084 private void startTabConversion() {
1085 if (fTabConverter == null) {
1086 fTabConverter = new TabConverter();
1087 configureTabConverter();
1088 fTabConverter.setNumberOfSpacesPerTab(getTabSize());
1089 AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
1090 asv.addTextConverter(fTabConverter);
1091 // http://dev.eclipse.org/bugs/show_bug.cgi?id=19270
1092 asv.updateIndentationPrefixes();
1096 private void stopTabConversion() {
1097 if (fTabConverter != null) {
1098 AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
1099 asv.removeTextConverter(fTabConverter);
1100 // http://dev.eclipse.org/bugs/show_bug.cgi?id=19270
1101 asv.updateIndentationPrefixes();
1102 fTabConverter = null;
1106 private boolean isTabConversionEnabled() {
1107 IPreferenceStore store = getPreferenceStore();
1108 return store.getBoolean(SPACES_FOR_TABS);
1111 private void showOverviewRuler() {
1112 AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
1113 asv.showOverviewRuler();
1115 OverviewRuler overviewRuler = asv.getOverviewRuler();
1116 if (overviewRuler != null) {
1117 for (int i = 0; i < ANNOTATION_LAYERS.length; i++) {
1118 AnnotationType type = ANNOTATION_LAYERS[i];
1119 overviewRuler.setLayer(type, i);
1120 if (isAnnotationIndicationInOverviewRulerEnabled(type))
1121 showAnnotationIndicationInOverviewRuler(type, true);
1126 private void hideOverviewRuler() {
1127 AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
1128 asv.hideOverviewRuler();
1131 private boolean isOverviewRulerVisible() {
1132 IPreferenceStore store = getPreferenceStore();
1133 return store.getBoolean(OVERVIEW_RULER);
1136 private Color getColor(String key) {
1137 RGB rgb = PreferenceConverter.getColor(getPreferenceStore(), key);
1138 return getColor(rgb);
1141 private Color getColor(RGB rgb) {
1142 JavaTextTools textTools = PHPeclipsePlugin.getDefault().getJavaTextTools();
1143 return textTools.getColorManager().getColor(rgb);
1146 private Color getColor(AnnotationType annotationType) {
1147 AnnotationInfo info = (AnnotationInfo) ANNOTATION_MAP.get(annotationType);
1149 return getColor(info.fColorPreference);
1153 public void dispose() {
1154 ISourceViewer sourceViewer= getSourceViewer();
1155 if (sourceViewer instanceof ITextViewerExtension)
1156 ((ITextViewerExtension) sourceViewer).removeVerifyKeyListener(fBracketInserter);
1158 if (fPropertyChangeListener != null) {
1159 Preferences preferences= PHPeclipsePlugin.getDefault().getPluginPreferences();
1160 preferences.removePropertyChangeListener(fPropertyChangeListener);
1161 fPropertyChangeListener= null;
1165 // if (fJavaEditorErrorTickUpdater != null) {
1166 // fJavaEditorErrorTickUpdater.dispose();
1167 // fJavaEditorErrorTickUpdater= null;
1170 // if (fSelectionHistory != null)
1171 // fSelectionHistory.dispose();
1173 if (fPaintManager != null) {
1174 fPaintManager.dispose();
1175 fPaintManager = null;
1178 if (fActionGroups != null)
1179 fActionGroups.dispose();
1184 protected AnnotationType getAnnotationType(String preferenceKey) {
1185 Iterator e= ANNOTATION_MAP.keySet().iterator();
1186 while (e.hasNext()) {
1187 AnnotationType type= (AnnotationType) e.next();
1188 AnnotationInfo info= (AnnotationInfo) ANNOTATION_MAP.get(type);
1190 if (preferenceKey.equals(info.fColorPreference) || preferenceKey.equals(info.fEditorPreference) || preferenceKey.equals(info.fOverviewRulerPreference))
1198 * @see AbstractTextEditor#handlePreferenceStoreChanged(PropertyChangeEvent)
1200 protected void handlePreferenceStoreChanged(PropertyChangeEvent event) {
1204 AdaptedSourceViewer asv= (AdaptedSourceViewer) getSourceViewer();
1207 String p= event.getProperty();
1209 if (CLOSE_BRACKETS.equals(p)) {
1210 fBracketInserter.setCloseBracketsEnabled(getPreferenceStore().getBoolean(p));
1214 if (CLOSE_STRINGS.equals(p)) {
1215 fBracketInserter.setCloseStringsEnabled(getPreferenceStore().getBoolean(p));
1219 if (SPACES_FOR_TABS.equals(p)) {
1220 if (isTabConversionEnabled())
1221 startTabConversion();
1223 stopTabConversion();
1227 if (MATCHING_BRACKETS.equals(p)) {
1228 if (isBracketHighlightingEnabled())
1229 startBracketHighlighting();
1231 stopBracketHighlighting();
1235 if (MATCHING_BRACKETS_COLOR.equals(p)) {
1236 if (fBracketPainter != null)
1237 fBracketPainter.setHighlightColor(getColor(MATCHING_BRACKETS_COLOR));
1241 if (CURRENT_LINE.equals(p)) {
1242 if (isLineHighlightingEnabled())
1243 startLineHighlighting();
1245 stopLineHighlighting();
1249 if (CURRENT_LINE_COLOR.equals(p)) {
1250 if (fLinePainter != null) {
1251 stopLineHighlighting();
1252 startLineHighlighting();
1257 if (PRINT_MARGIN.equals(p)) {
1258 if (isPrintMarginVisible())
1265 if (PRINT_MARGIN_COLOR.equals(p)) {
1266 if (fPrintMarginPainter != null)
1267 fPrintMarginPainter.setMarginRulerColor(getColor(PRINT_MARGIN_COLOR));
1271 if (PRINT_MARGIN_COLUMN.equals(p)) {
1272 if (fPrintMarginPainter != null)
1273 fPrintMarginPainter.setMarginRulerColumn(getPreferenceStore().getInt(PRINT_MARGIN_COLUMN));
1277 if (OVERVIEW_RULER.equals(p)) {
1278 if (isOverviewRulerVisible())
1279 showOverviewRuler();
1281 hideOverviewRuler();
1285 AnnotationType type= getAnnotationType(p);
1288 AnnotationInfo info= (AnnotationInfo) ANNOTATION_MAP.get(type);
1289 if (info.fColorPreference.equals(p)) {
1290 Color color= getColor(type);
1291 if (fProblemPainter != null) {
1292 fProblemPainter.setColor(type, color);
1293 fProblemPainter.paint(IPainter.CONFIGURATION);
1295 setColorInOverviewRuler(type, color);
1299 if (info.fEditorPreference.equals(p)) {
1300 if (isAnnotationIndicationEnabled(type))
1301 startAnnotationIndication(type);
1303 stopAnnotationIndication(type);
1307 if (info.fOverviewRulerPreference.equals(p)) {
1308 if (isAnnotationIndicationInOverviewRulerEnabled(type))
1309 showAnnotationIndicationInOverviewRuler(type, true);
1311 showAnnotationIndicationInOverviewRuler(type, false);
1316 IContentAssistant c= asv.getContentAssistant();
1317 if (c instanceof ContentAssistant)
1318 ContentAssistPreference.changeConfiguration((ContentAssistant) c, getPreferenceStore(), event);
1322 super.handlePreferenceStoreChanged(event);
1327 * Handles a property change event describing a change
1328 * of the php core's preferences and updates the preference
1329 * related editor properties.
1331 * @param event the property change event
1333 protected void handlePreferencePropertyChanged(org.eclipse.core.runtime.Preferences.PropertyChangeEvent event) {
1334 AdaptedSourceViewer asv= (AdaptedSourceViewer) getSourceViewer();
1336 String p= event.getProperty();
1337 if (CODE_FORMATTER_TAB_SIZE.equals(p)) {
1338 asv.updateIndentationPrefixes();
1339 if (fTabConverter != null)
1340 fTabConverter.setNumberOfSpacesPerTab(getTabSize());
1346 * @see PHPEditor#createJavaSourceViewer(Composite, IVerticalRuler, int)
1348 protected ISourceViewer createJavaSourceViewer(Composite parent, IVerticalRuler ruler, int styles) {
1349 return new AdaptedSourceViewer(parent, ruler, styles);
1352 private boolean isValidSelection(int offset, int length) {
1353 IDocumentProvider provider= getDocumentProvider();
1354 if (provider != null) {
1355 IDocument document= provider.getDocument(getEditorInput());
1356 if (document != null) {
1357 int end= offset + length;
1358 int documentLength= document.getLength();
1359 return 0 <= offset && offset <= documentLength && 0 <= end && end <= documentLength;
1366 * @see AbstractTextEditor#canHandleMove(IEditorInput, IEditorInput)
1368 protected boolean canHandleMove(IEditorInput originalElement, IEditorInput movedElement) {
1370 String oldExtension= ""; //$NON-NLS-1$
1371 if (originalElement instanceof IFileEditorInput) {
1372 IFile file= ((IFileEditorInput) originalElement).getFile();
1374 String ext= file.getFileExtension();
1380 String newExtension= ""; //$NON-NLS-1$
1381 if (movedElement instanceof IFileEditorInput) {
1382 IFile file= ((IFileEditorInput) movedElement).getFile();
1384 newExtension= file.getFileExtension();
1387 return oldExtension.equals(newExtension);