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.phpeclipse.PHPCore;
16 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
18 import org.eclipse.core.resources.IFile;
19 import org.eclipse.core.runtime.CoreException;
20 import org.eclipse.core.runtime.Preferences;
21 import org.eclipse.core.runtime.Preferences.IPropertyChangeListener;
22 import org.eclipse.jface.preference.IPreferenceStore;
23 import org.eclipse.jface.preference.PreferenceConverter;
24 import org.eclipse.jface.text.AbstractHoverInformationControlManager;
25 import org.eclipse.jface.text.BadLocationException;
26 import org.eclipse.jface.text.DocumentCommand;
27 import org.eclipse.jface.text.IDocument;
28 import org.eclipse.jface.text.ILineTracker;
29 import org.eclipse.jface.text.IRegion;
30 import org.eclipse.jface.text.ITextSelection;
31 import org.eclipse.jface.text.ITextViewerExtension;
32 import org.eclipse.jface.text.ITypedRegion;
33 import org.eclipse.jface.text.IWidgetTokenKeeper;
34 import org.eclipse.jface.text.contentassist.ContentAssistant;
35 import org.eclipse.jface.text.contentassist.IContentAssistant;
36 import org.eclipse.jface.text.source.IAnnotationModel;
37 import org.eclipse.jface.text.source.ISourceViewer;
38 import org.eclipse.jface.text.source.IVerticalRuler;
39 import org.eclipse.jface.text.source.SourceViewer;
40 import org.eclipse.jface.text.source.SourceViewerConfiguration;
41 import org.eclipse.jface.util.PropertyChangeEvent;
42 import org.eclipse.swt.SWT;
43 import org.eclipse.swt.custom.StyledText;
44 import org.eclipse.swt.custom.VerifyKeyListener;
45 import org.eclipse.swt.events.VerifyEvent;
46 import org.eclipse.swt.graphics.Color;
47 import org.eclipse.swt.graphics.Point;
48 import org.eclipse.swt.graphics.RGB;
49 import org.eclipse.swt.graphics.Rectangle;
50 import org.eclipse.swt.widgets.Composite;
51 import org.eclipse.swt.widgets.Control;
52 import org.eclipse.swt.widgets.Display;
53 import org.eclipse.swt.widgets.Layout;
54 import org.eclipse.ui.IEditorInput;
55 import org.eclipse.ui.IFileEditorInput;
56 import org.eclipse.ui.help.WorkbenchHelp;
57 import org.eclipse.ui.texteditor.IDocumentProvider;
59 /**********************************************************************
60 Copyright (c) 2000, 2002 IBM Corp. and others.
61 All rights reserved. This program and the accompanying materials
62 are made available under the terms of the Common Public License v1.0
63 which accompanies this distribution, and is available at
64 http://www.eclipse.org/legal/cpl-v10.html
67 IBM Corporation - Initial implementation
68 Klaus Hartlage - www.eclipseproject.de
69 **********************************************************************/
71 * PHP specific text editor.
73 public class PHPUnitEditor extends PHPEditor {
74 interface ITextConverter {
75 void customizeDocumentCommand(IDocument document, DocumentCommand command);
78 class AdaptedRulerLayout extends Layout {
81 protected AdaptedSourceViewer fAdaptedSourceViewer;
83 protected AdaptedRulerLayout(int gap, AdaptedSourceViewer asv) {
85 fAdaptedSourceViewer = asv;
88 protected Point computeSize(
93 Control[] children = composite.getChildren();
95 children[children.length
96 - 1].computeSize(SWT.DEFAULT, SWT.DEFAULT, flushCache);
97 if (fAdaptedSourceViewer.isVerticalRulerVisible())
98 s.x += fAdaptedSourceViewer.getVerticalRuler().getWidth() + fGap;
102 protected void layout(Composite composite, boolean flushCache) {
103 Rectangle clArea = composite.getClientArea();
104 if (fAdaptedSourceViewer.isVerticalRulerVisible()) {
106 StyledText textWidget = fAdaptedSourceViewer.getTextWidget();
107 Rectangle trim = textWidget.computeTrim(0, 0, 0, 0);
108 int scrollbarHeight = trim.height;
110 IVerticalRuler vr = fAdaptedSourceViewer.getVerticalRuler();
111 int vrWidth = vr.getWidth();
114 if (fAdaptedSourceViewer.isOverviewRulerVisible()) {
115 OverviewRuler or = fAdaptedSourceViewer.getOverviewRuler();
116 orWidth = or.getWidth();
117 or.getControl().setBounds(
118 clArea.width - orWidth,
121 clArea.height - 3 * scrollbarHeight);
124 textWidget.setBounds(
127 clArea.width - vrWidth - orWidth - 2 * fGap,
129 vr.getControl().setBounds(
133 clArea.height - scrollbarHeight);
136 StyledText textWidget = fAdaptedSourceViewer.getTextWidget();
137 textWidget.setBounds(0, 0, clArea.width, clArea.height);
142 class AdaptedSourceViewer
143 extends SourceViewer { // extends JavaCorrectionSourceViewer {
145 private List fTextConverters;
147 private OverviewRuler fOverviewRuler;
148 private boolean fIsOverviewRulerVisible;
149 /** The viewer's overview ruler hovering controller */
150 private AbstractHoverInformationControlManager fOverviewRulerHoveringController;
152 private boolean fIgnoreTextConverters = false;
154 private IVerticalRuler fCachedVerticalRuler;
155 private boolean fCachedIsVerticalRulerVisible;
157 public AdaptedSourceViewer(
159 IVerticalRuler ruler,
161 super(parent, ruler, styles); //, CompilationUnitEditor.this);
163 fCachedVerticalRuler = ruler;
164 fCachedIsVerticalRulerVisible = (ruler != null);
165 fOverviewRuler = new OverviewRuler(VERTICAL_RULER_WIDTH);
167 delayedCreateControl(parent, styles);
171 * @see ISourceViewer#showAnnotations(boolean)
173 public void showAnnotations(boolean show) {
174 fCachedIsVerticalRulerVisible = (show && fCachedVerticalRuler != null);
175 // super.showAnnotations(show);
178 public IContentAssistant getContentAssistant() {
179 return fContentAssistant;
183 * @see ITextOperationTarget#doOperation(int)
185 public void doOperation(int operation) {
187 if (getTextWidget() == null)
191 case CONTENTASSIST_PROPOSALS :
192 String msg = fContentAssistant.showPossibleCompletions();
193 setStatusLineErrorMessage(msg);
196 fIgnoreTextConverters = true;
199 fIgnoreTextConverters = true;
203 super.doOperation(operation);
206 public void insertTextConverter(ITextConverter textConverter, int index) {
207 throw new UnsupportedOperationException();
210 public void addTextConverter(ITextConverter textConverter) {
211 if (fTextConverters == null) {
212 fTextConverters = new ArrayList(1);
213 fTextConverters.add(textConverter);
214 } else if (!fTextConverters.contains(textConverter))
215 fTextConverters.add(textConverter);
218 public void removeTextConverter(ITextConverter textConverter) {
219 if (fTextConverters != null) {
220 fTextConverters.remove(textConverter);
221 if (fTextConverters.size() == 0)
222 fTextConverters = null;
227 * @see TextViewer#customizeDocumentCommand(DocumentCommand)
229 protected void customizeDocumentCommand(DocumentCommand command) {
230 super.customizeDocumentCommand(command);
231 if (!fIgnoreTextConverters && fTextConverters != null) {
232 for (Iterator e = fTextConverters.iterator(); e.hasNext();)
233 ((ITextConverter) e.next()).customizeDocumentCommand(
237 fIgnoreTextConverters = false;
240 public IVerticalRuler getVerticalRuler() {
241 return fCachedVerticalRuler;
244 public boolean isVerticalRulerVisible() {
245 return fCachedIsVerticalRulerVisible;
248 public OverviewRuler getOverviewRuler() {
249 return fOverviewRuler;
253 * @see TextViewer#createControl(Composite, int)
255 protected void createControl(Composite parent, int styles) {
259 protected void delayedCreateControl(Composite parent, int styles) {
261 super.createControl(parent, styles);
263 Control control = getControl();
264 if (control instanceof Composite) {
265 Composite composite = (Composite) control;
266 composite.setLayout(new AdaptedRulerLayout(GAP_SIZE, this));
267 fOverviewRuler.createControl(composite, this);
271 protected void ensureOverviewHoverManagerInstalled() {
272 if (fOverviewRulerHoveringController == null
273 && fAnnotationHover != null
274 && fHoverControlCreator != null) {
275 fOverviewRulerHoveringController =
276 new OverviewRulerHoverManager(
280 fHoverControlCreator);
281 fOverviewRulerHoveringController.install(fOverviewRuler.getControl());
285 public void hideOverviewRuler() {
286 fIsOverviewRulerVisible = false;
287 Control control = getControl();
288 if (control instanceof Composite) {
289 Composite composite = (Composite) control;
292 if (fOverviewRulerHoveringController != null) {
293 fOverviewRulerHoveringController.dispose();
294 fOverviewRulerHoveringController = null;
298 public void showOverviewRuler() {
299 fIsOverviewRulerVisible = true;
300 Control control = getControl();
301 if (control instanceof Composite) {
302 Composite composite = (Composite) control;
305 ensureOverviewHoverManagerInstalled();
308 public boolean isOverviewRulerVisible() {
309 return fIsOverviewRulerVisible;
313 * @see ISourceViewer#setDocument(IDocument, IAnnotationModel, int, int)
315 public void setDocument(
317 IAnnotationModel annotationModel,
318 int visibleRegionOffset,
319 int visibleRegionLength) {
324 visibleRegionLength);
325 fOverviewRuler.setModel(annotationModel);
328 // http://dev.eclipse.org/bugs/show_bug.cgi?id=19270
329 public void updateIndentationPrefixes() {
330 SourceViewerConfiguration configuration = getSourceViewerConfiguration();
331 String[] types = configuration.getConfiguredContentTypes(this);
332 for (int i = 0; i < types.length; i++) {
333 String[] prefixes = configuration.getIndentPrefixes(this, types[i]);
334 if (prefixes != null && prefixes.length > 0)
335 setIndentPrefixes(prefixes, types[i]);
340 * @see IWidgetTokenOwner#requestWidgetToken(IWidgetTokenKeeper)
342 public boolean requestWidgetToken(IWidgetTokenKeeper requester) {
343 if (WorkbenchHelp.isContextHelpDisplayed())
345 return super.requestWidgetToken(requester);
349 * @see org.eclipse.jface.text.source.ISourceViewer#configure(org.eclipse.jface.text.source.SourceViewerConfiguration)
351 public void configure(SourceViewerConfiguration configuration) {
352 super.configure(configuration);
353 // prependAutoEditStrategy(new SmartBracesAutoEditStrategy(this), IDocument.DEFAULT_CONTENT_TYPE);
356 protected void handleDispose() {
357 fOverviewRuler = null;
359 if (fOverviewRulerHoveringController != null) {
360 fOverviewRulerHoveringController.dispose();
361 fOverviewRulerHoveringController = null;
364 super.handleDispose();
369 static class TabConverter implements ITextConverter {
371 private int fTabRatio;
372 private ILineTracker fLineTracker;
374 public TabConverter() {
377 public void setNumberOfSpacesPerTab(int ratio) {
381 public void setLineTracker(ILineTracker lineTracker) {
382 fLineTracker = lineTracker;
385 private int insertTabString(StringBuffer buffer, int offsetInLine) {
390 int remainder = offsetInLine % fTabRatio;
391 remainder = fTabRatio - remainder;
392 for (int i = 0; i < remainder; i++)
397 public void customizeDocumentCommand(
399 DocumentCommand command) {
400 String text = command.text;
404 int index = text.indexOf('\t');
407 StringBuffer buffer = new StringBuffer();
409 fLineTracker.set(command.text);
410 int lines = fLineTracker.getNumberOfLines();
414 for (int i = 0; i < lines; i++) {
416 int offset = fLineTracker.getLineOffset(i);
417 int endOffset = offset + fLineTracker.getLineLength(i);
418 String line = text.substring(offset, endOffset);
423 document.getLineInformationOfOffset(command.offset);
424 position = command.offset - firstLine.getOffset();
427 int length = line.length();
428 for (int j = 0; j < length; j++) {
429 char c = line.charAt(j);
431 position += insertTabString(buffer, position);
440 command.text = buffer.toString();
442 } catch (BadLocationException x) {
448 private static class ExitPolicy implements LinkedPositionUI.ExitPolicy {
450 final char fExitCharacter;
452 public ExitPolicy(char exitCharacter) {
453 fExitCharacter= exitCharacter;
457 * @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)
459 public ExitFlags doExit(LinkedPositionManager manager, VerifyEvent event, int offset, int length) {
461 if (event.character == fExitCharacter) {
462 if (manager.anyPositionIncludes(offset, length))
463 return new ExitFlags(LinkedPositionUI.COMMIT| LinkedPositionUI.UPDATE_CARET, false);
465 return new ExitFlags(LinkedPositionUI.COMMIT, true);
468 switch (event.character) {
470 if (manager.getFirstPosition().length == 0)
471 return new ExitFlags(0, false);
477 return new ExitFlags(LinkedPositionUI.COMMIT, true);
485 private class BracketInserter implements VerifyKeyListener, LinkedPositionUI.ExitListener {
487 private boolean fCloseBrackets= true;
488 private boolean fCloseStrings= true;
493 public void setCloseBracketsEnabled(boolean enabled) {
494 fCloseBrackets= enabled;
497 public void setCloseStringsEnabled(boolean enabled) {
498 fCloseStrings= enabled;
501 private boolean hasIdentifierToTheRight(IDocument document, int offset) {
504 IRegion endLine= document.getLineInformationOfOffset(end);
505 int maxEnd= endLine.getOffset() + endLine.getLength();
506 while (end != maxEnd && Character.isWhitespace(document.getChar(end)))
509 return end != maxEnd && Character.isJavaIdentifierPart(document.getChar(end));
511 } catch (BadLocationException e) {
517 private boolean hasIdentifierToTheLeft(IDocument document, int offset) {
520 IRegion startLine= document.getLineInformationOfOffset(start);
521 int minStart= startLine.getOffset();
522 while (start != minStart && Character.isWhitespace(document.getChar(start - 1)))
525 return start != minStart && Character.isJavaIdentifierPart(document.getChar(start - 1));
527 } catch (BadLocationException e) {
532 private boolean hasCharacterToTheRight(IDocument document, int offset, char character) {
535 IRegion endLine= document.getLineInformationOfOffset(end);
536 int maxEnd= endLine.getOffset() + endLine.getLength();
537 while (end != maxEnd && Character.isWhitespace(document.getChar(end)))
540 return end != maxEnd && document.getChar(end) == character;
543 } catch (BadLocationException e) {
550 * @see org.eclipse.swt.custom.VerifyKeyListener#verifyKey(org.eclipse.swt.events.VerifyEvent)
552 public void verifyKey(VerifyEvent event) {
557 final ISourceViewer sourceViewer= getSourceViewer();
558 IDocument document= sourceViewer.getDocument();
560 final Point selection= sourceViewer.getSelectedRange();
561 final int offset= selection.x;
562 final int length= selection.y;
564 switch (event.character) {
566 if (hasCharacterToTheRight(document, offset + length, '('))
574 if (hasIdentifierToTheRight(document, offset + length))
580 if (event.character == '"') {
583 if (hasIdentifierToTheLeft(document, offset) || hasIdentifierToTheRight(document, offset + length))
588 ITypedRegion partition= document.getPartition(offset);
589 if (! IDocument.DEFAULT_CONTENT_TYPE.equals(partition.getType()) && partition.getOffset() != offset)
592 final char character= event.character;
593 final char closingCharacter= getPeerCharacter(character);
594 final StringBuffer buffer= new StringBuffer();
595 buffer.append(character);
596 buffer.append(closingCharacter);
598 document.replace(offset, length, buffer.toString());
600 LinkedPositionManager manager= new LinkedPositionManager(document);
601 manager.addPosition(offset + 1, 0);
606 LinkedPositionUI editor= new LinkedPositionUI(sourceViewer, manager);
607 editor.setCancelListener(this);
608 editor.setExitPolicy(new ExitPolicy(closingCharacter));
609 editor.setFinalCaretOffset(offset + 2);
612 IRegion newSelection= editor.getSelectedRegion();
613 sourceViewer.setSelectedRange(newSelection.getOffset(), newSelection.getLength());
617 } catch (BadLocationException e) {
624 * @see org.phpeclipse.phpdt.internal.ui.text.link.LinkedPositionUI.ExitListener#exit(boolean)
626 public void exit(boolean accept) {
632 final ISourceViewer sourceViewer= getSourceViewer();
633 IDocument document= sourceViewer.getDocument();
634 document.replace(fOffset, fLength, null);
635 } catch (BadLocationException e) {
640 /** The editor's paint manager */
641 private PaintManager fPaintManager;
642 /** The editor's bracket painter */
643 private BracketPainter fBracketPainter;
644 /** The editor's bracket matcher */
645 private PHPPairMatcher fBracketMatcher;
646 /** The editor's line painter */
647 private LinePainter fLinePainter;
648 /** The editor's print margin ruler painter */
649 private PrintMarginPainter fPrintMarginPainter;
650 /** The editor's problem painter */
651 private ProblemPainter fProblemPainter;
652 /** The editor's tab converter */
653 private TabConverter fTabConverter;
654 /** History for structure select action */
655 //private SelectionHistory fSelectionHistory;
657 /** The preference property change listener for php core. */
658 private IPropertyChangeListener fPropertyChangeListener= new PropertyChangeListener();
659 /** The remembered selection */
660 private ITextSelection fRememberedSelection;
661 /** The remembered php element offset */
662 private int fRememberedElementOffset;
663 /** The bracket inserter. */
664 private BracketInserter fBracketInserter= new BracketInserter();
666 private class PropertyChangeListener implements IPropertyChangeListener {
668 * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
670 public void propertyChange(org.eclipse.core.runtime.Preferences.PropertyChangeEvent event) {
671 handlePreferencePropertyChanged(event);
674 /* Preference key for code formatter tab size */
675 private final static String CODE_FORMATTER_TAB_SIZE =
676 PHPCore.FORMATTER_TAB_SIZE;
677 /** Preference key for matching brackets */
678 private final static String MATCHING_BRACKETS =
679 PreferenceConstants.EDITOR_MATCHING_BRACKETS;
680 /** Preference key for matching brackets color */
681 private final static String MATCHING_BRACKETS_COLOR =
682 PreferenceConstants.EDITOR_MATCHING_BRACKETS_COLOR;
683 /** Preference key for highlighting current line */
684 private final static String CURRENT_LINE =
685 PreferenceConstants.EDITOR_CURRENT_LINE;
686 /** Preference key for highlight color of current line */
687 private final static String CURRENT_LINE_COLOR =
688 PreferenceConstants.EDITOR_CURRENT_LINE_COLOR;
689 /** Preference key for showing print marging ruler */
690 private final static String PRINT_MARGIN =
691 PreferenceConstants.EDITOR_PRINT_MARGIN;
692 /** Preference key for print margin ruler color */
693 private final static String PRINT_MARGIN_COLOR =
694 PreferenceConstants.EDITOR_PRINT_MARGIN_COLOR;
695 /** Preference key for print margin ruler column */
696 private final static String PRINT_MARGIN_COLUMN =
697 PreferenceConstants.EDITOR_PRINT_MARGIN_COLUMN;
698 /** Preference key for inserting spaces rather than tabs */
699 private final static String SPACES_FOR_TABS =
700 PreferenceConstants.EDITOR_SPACES_FOR_TABS;
701 /** Preference key for error indication */
702 private final static String ERROR_INDICATION =
703 PreferenceConstants.EDITOR_PROBLEM_INDICATION;
704 /** Preference key for error color */
705 private final static String ERROR_INDICATION_COLOR =
706 PreferenceConstants.EDITOR_PROBLEM_INDICATION_COLOR;
707 /** Preference key for warning indication */
708 private final static String WARNING_INDICATION =
709 PreferenceConstants.EDITOR_WARNING_INDICATION;
710 /** Preference key for warning color */
711 private final static String WARNING_INDICATION_COLOR =
712 PreferenceConstants.EDITOR_WARNING_INDICATION_COLOR;
713 /** Preference key for task indication */
714 private final static String TASK_INDICATION =
715 PreferenceConstants.EDITOR_TASK_INDICATION;
716 /** Preference key for task color */
717 private final static String TASK_INDICATION_COLOR =
718 PreferenceConstants.EDITOR_TASK_INDICATION_COLOR;
719 /** Preference key for bookmark indication */
720 private final static String BOOKMARK_INDICATION =
721 PreferenceConstants.EDITOR_BOOKMARK_INDICATION;
722 /** Preference key for bookmark color */
723 private final static String BOOKMARK_INDICATION_COLOR =
724 PreferenceConstants.EDITOR_BOOKMARK_INDICATION_COLOR;
725 /** Preference key for search result indication */
726 private final static String SEARCH_RESULT_INDICATION =
727 PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION;
728 /** Preference key for search result color */
729 private final static String SEARCH_RESULT_INDICATION_COLOR =
730 PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION_COLOR;
731 /** Preference key for unknown annotation indication */
732 private final static String UNKNOWN_INDICATION =
733 PreferenceConstants.EDITOR_UNKNOWN_INDICATION;
734 /** Preference key for unknown annotation color */
735 private final static String UNKNOWN_INDICATION_COLOR =
736 PreferenceConstants.EDITOR_UNKNOWN_INDICATION_COLOR;
737 /** Preference key for linked position color */
738 private final static String LINKED_POSITION_COLOR =
739 PreferenceConstants.EDITOR_LINKED_POSITION_COLOR;
740 /** Preference key for shwoing the overview ruler */
741 private final static String OVERVIEW_RULER =
742 PreferenceConstants.EDITOR_OVERVIEW_RULER;
744 /** Preference key for error indication in overview ruler */
745 private final static String ERROR_INDICATION_IN_OVERVIEW_RULER =
746 PreferenceConstants.EDITOR_ERROR_INDICATION_IN_OVERVIEW_RULER;
747 /** Preference key for warning indication in overview ruler */
748 private final static String WARNING_INDICATION_IN_OVERVIEW_RULER =
749 PreferenceConstants.EDITOR_WARNING_INDICATION_IN_OVERVIEW_RULER;
750 /** Preference key for task indication in overview ruler */
751 private final static String TASK_INDICATION_IN_OVERVIEW_RULER =
752 PreferenceConstants.EDITOR_TASK_INDICATION_IN_OVERVIEW_RULER;
753 /** Preference key for bookmark indication in overview ruler */
754 private final static String BOOKMARK_INDICATION_IN_OVERVIEW_RULER =
755 PreferenceConstants.EDITOR_BOOKMARK_INDICATION_IN_OVERVIEW_RULER;
756 /** Preference key for search result indication in overview ruler */
757 private final static String SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER =
758 PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER;
759 /** Preference key for unknown annotation indication in overview ruler */
760 private final static String UNKNOWN_INDICATION_IN_OVERVIEW_RULER =
761 PreferenceConstants.EDITOR_UNKNOWN_INDICATION_IN_OVERVIEW_RULER;
762 /** Preference key for automatically closing strings */
763 private final static String CLOSE_STRINGS= PreferenceConstants.EDITOR_CLOSE_STRINGS;
764 /** Preference key for automatically wrapping Java strings */
765 private final static String WRAP_STRINGS= PreferenceConstants.EDITOR_WRAP_STRINGS;
766 /** Preference key for automatically closing brackets and parenthesis */
767 private final static String CLOSE_BRACKETS= PreferenceConstants.EDITOR_CLOSE_BRACKETS;
768 /** Preference key for automatically closing phpdocs and comments */
769 private final static String CLOSE_JAVADOCS= PreferenceConstants.EDITOR_CLOSE_JAVADOCS;
770 /** Preference key for automatically adding phpdoc tags */
771 private final static String ADD_JAVADOC_TAGS= PreferenceConstants.EDITOR_ADD_JAVADOC_TAGS;
772 /** Preference key for automatically formatting phpdocs */
773 private final static String FORMAT_JAVADOCS= PreferenceConstants.EDITOR_FORMAT_JAVADOCS;
774 /** Preference key for smart paste */
775 private final static String SMART_PASTE= PreferenceConstants.EDITOR_SMART_PASTE;
776 private final static class AnnotationInfo {
777 public String fColorPreference;
778 public String fOverviewRulerPreference;
779 public String fEditorPreference;
782 private final static Map ANNOTATION_MAP;
786 ANNOTATION_MAP = new HashMap();
788 info = new AnnotationInfo();
789 info.fColorPreference = TASK_INDICATION_COLOR;
790 info.fOverviewRulerPreference = TASK_INDICATION_IN_OVERVIEW_RULER;
791 info.fEditorPreference = TASK_INDICATION;
792 ANNOTATION_MAP.put(AnnotationType.TASK, info);
794 info = new AnnotationInfo();
795 info.fColorPreference = ERROR_INDICATION_COLOR;
796 info.fOverviewRulerPreference = ERROR_INDICATION_IN_OVERVIEW_RULER;
797 info.fEditorPreference = ERROR_INDICATION;
798 ANNOTATION_MAP.put(AnnotationType.ERROR, info);
800 info = new AnnotationInfo();
801 info.fColorPreference = WARNING_INDICATION_COLOR;
802 info.fOverviewRulerPreference = WARNING_INDICATION_IN_OVERVIEW_RULER;
803 info.fEditorPreference = WARNING_INDICATION;
804 ANNOTATION_MAP.put(AnnotationType.WARNING, info);
806 info = new AnnotationInfo();
807 info.fColorPreference = BOOKMARK_INDICATION_COLOR;
808 info.fOverviewRulerPreference = BOOKMARK_INDICATION_IN_OVERVIEW_RULER;
809 info.fEditorPreference = BOOKMARK_INDICATION;
810 ANNOTATION_MAP.put(AnnotationType.BOOKMARK, info);
812 info = new AnnotationInfo();
813 info.fColorPreference = SEARCH_RESULT_INDICATION_COLOR;
814 info.fOverviewRulerPreference = SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER;
815 info.fEditorPreference = SEARCH_RESULT_INDICATION;
816 ANNOTATION_MAP.put(AnnotationType.SEARCH_RESULT, info);
818 info = new AnnotationInfo();
819 info.fColorPreference = UNKNOWN_INDICATION_COLOR;
820 info.fOverviewRulerPreference = UNKNOWN_INDICATION_IN_OVERVIEW_RULER;
821 info.fEditorPreference = UNKNOWN_INDICATION;
822 ANNOTATION_MAP.put(AnnotationType.UNKNOWN, info);
825 private final static AnnotationType[] ANNOTATION_LAYERS =
826 new AnnotationType[] {
827 AnnotationType.UNKNOWN,
828 AnnotationType.BOOKMARK,
830 AnnotationType.SEARCH_RESULT,
831 AnnotationType.WARNING,
832 AnnotationType.ERROR };
835 * Creates a new php unit editor.
837 public PHPUnitEditor() {
839 setDocumentProvider(PHPeclipsePlugin.getDefault().getCompilationUnitDocumentProvider());
840 setEditorContextMenuId("#PHPEditorContext"); //$NON-NLS-1$
841 setRulerContextMenuId("#PHPRulerContext"); //$NON-NLS-1$
845 public void createPartControl(Composite parent) {
846 super.createPartControl(parent);
848 fPaintManager = new PaintManager(getSourceViewer());
850 LinePainter linePainter;
851 linePainter = new LinePainter(getSourceViewer());
853 linePainter.setHighlightColor(
854 new Color(Display.getCurrent(), 225, 235, 224));
856 fPaintManager.addPainter(linePainter);
859 if (isBracketHighlightingEnabled())
860 startBracketHighlighting();
861 if (isLineHighlightingEnabled())
862 startLineHighlighting();
863 if (isPrintMarginVisible())
867 Iterator e= ANNOTATION_MAP.keySet().iterator();
868 while (e.hasNext()) {
869 AnnotationType type= (AnnotationType) e.next();
870 if (isAnnotationIndicationEnabled(type))
871 startAnnotationIndication(type);
874 if (isTabConversionEnabled())
875 startTabConversion();
877 if (isOverviewRulerVisible())
881 Preferences preferences= PHPeclipsePlugin.getDefault().getPluginPreferences();
882 preferences.addPropertyChangeListener(fPropertyChangeListener);
884 IPreferenceStore preferenceStore= getPreferenceStore();
885 boolean closeBrackets= preferenceStore.getBoolean(CLOSE_BRACKETS);
886 boolean closeStrings= preferenceStore.getBoolean(CLOSE_STRINGS);
888 fBracketInserter.setCloseBracketsEnabled(closeBrackets);
889 fBracketInserter.setCloseStringsEnabled(closeStrings);
891 ISourceViewer sourceViewer= getSourceViewer();
892 if (sourceViewer instanceof ITextViewerExtension)
893 ((ITextViewerExtension) sourceViewer).prependVerifyKeyListener(fBracketInserter);
897 private static char getPeerCharacter(char character) {
915 throw new IllegalArgumentException();
920 * @see AbstractTextEditor#doSetInput(IEditorInput)
922 protected void doSetInput(IEditorInput input) throws CoreException {
923 super.doSetInput(input);
924 configureTabConverter();
927 private void startBracketHighlighting() {
928 if (fBracketPainter == null) {
929 ISourceViewer sourceViewer = getSourceViewer();
930 fBracketPainter = new BracketPainter(sourceViewer);
931 fBracketPainter.setHighlightColor(getColor(MATCHING_BRACKETS_COLOR));
932 fPaintManager.addPainter(fBracketPainter);
936 private void stopBracketHighlighting() {
937 if (fBracketPainter != null) {
938 fPaintManager.removePainter(fBracketPainter);
939 fBracketPainter.deactivate(true);
940 fBracketPainter.dispose();
941 fBracketPainter = null;
945 private boolean isBracketHighlightingEnabled() {
946 IPreferenceStore store = getPreferenceStore();
947 return store.getBoolean(MATCHING_BRACKETS);
950 private void startLineHighlighting() {
951 if (fLinePainter == null) {
952 ISourceViewer sourceViewer = getSourceViewer();
953 fLinePainter = new LinePainter(sourceViewer);
954 fLinePainter.setHighlightColor(getColor(CURRENT_LINE_COLOR));
955 fPaintManager.addPainter(fLinePainter);
959 private void stopLineHighlighting() {
960 if (fLinePainter != null) {
961 fPaintManager.removePainter(fLinePainter);
962 fLinePainter.deactivate(true);
963 fLinePainter.dispose();
968 private boolean isLineHighlightingEnabled() {
969 IPreferenceStore store = getPreferenceStore();
970 return store.getBoolean(CURRENT_LINE);
973 private void showPrintMargin() {
974 if (fPrintMarginPainter == null) {
975 fPrintMarginPainter = new PrintMarginPainter(getSourceViewer());
976 fPrintMarginPainter.setMarginRulerColor(getColor(PRINT_MARGIN_COLOR));
977 fPrintMarginPainter.setMarginRulerColumn(
978 getPreferenceStore().getInt(PRINT_MARGIN_COLUMN));
979 fPaintManager.addPainter(fPrintMarginPainter);
983 private void hidePrintMargin() {
984 if (fPrintMarginPainter != null) {
985 fPaintManager.removePainter(fPrintMarginPainter);
986 fPrintMarginPainter.deactivate(true);
987 fPrintMarginPainter.dispose();
988 fPrintMarginPainter = null;
992 private boolean isPrintMarginVisible() {
993 IPreferenceStore store = getPreferenceStore();
994 return store.getBoolean(PRINT_MARGIN);
997 private void startAnnotationIndication(AnnotationType annotationType) {
998 if (fProblemPainter == null) {
999 fProblemPainter = new ProblemPainter(this, getSourceViewer());
1000 fPaintManager.addPainter(fProblemPainter);
1002 fProblemPainter.setColor(annotationType, getColor(annotationType));
1003 fProblemPainter.paintAnnotations(annotationType, true);
1004 fProblemPainter.paint(IPainter.CONFIGURATION);
1007 private void shutdownAnnotationIndication() {
1008 if (fProblemPainter != null) {
1010 if (!fProblemPainter.isPaintingAnnotations()) {
1011 fPaintManager.removePainter(fProblemPainter);
1012 fProblemPainter.deactivate(true);
1013 fProblemPainter.dispose();
1014 fProblemPainter = null;
1016 fProblemPainter.paint(IPainter.CONFIGURATION);
1021 private void stopAnnotationIndication(AnnotationType annotationType) {
1022 if (fProblemPainter != null) {
1023 fProblemPainter.paintAnnotations(annotationType, false);
1024 shutdownAnnotationIndication();
1028 private boolean isAnnotationIndicationEnabled(AnnotationType annotationType) {
1029 IPreferenceStore store = getPreferenceStore();
1030 AnnotationInfo info = (AnnotationInfo) ANNOTATION_MAP.get(annotationType);
1032 return store.getBoolean(info.fEditorPreference);
1036 private boolean isAnnotationIndicationInOverviewRulerEnabled(AnnotationType annotationType) {
1037 IPreferenceStore store = getPreferenceStore();
1038 AnnotationInfo info = (AnnotationInfo) ANNOTATION_MAP.get(annotationType);
1040 return store.getBoolean(info.fOverviewRulerPreference);
1044 private void showAnnotationIndicationInOverviewRuler(
1045 AnnotationType annotationType,
1047 AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
1048 OverviewRuler ruler = asv.getOverviewRuler();
1049 if (ruler != null) {
1050 ruler.setColor(annotationType, getColor(annotationType));
1051 ruler.showAnnotation(annotationType, show);
1056 private void setColorInOverviewRuler(
1057 AnnotationType annotationType,
1059 AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
1060 OverviewRuler ruler = asv.getOverviewRuler();
1061 if (ruler != null) {
1062 ruler.setColor(annotationType, color);
1067 private void configureTabConverter() {
1068 if (fTabConverter != null) {
1069 IDocumentProvider provider = getDocumentProvider();
1070 if (provider instanceof PHPDocumentProvider) {
1071 PHPDocumentProvider cup = (PHPDocumentProvider) provider;
1072 fTabConverter.setLineTracker(cup.createLineTracker(getEditorInput()));
1077 private int getTabSize() {
1078 Preferences preferences =
1079 PHPeclipsePlugin.getDefault().getPluginPreferences();
1080 return preferences.getInt(CODE_FORMATTER_TAB_SIZE);
1083 private void startTabConversion() {
1084 if (fTabConverter == null) {
1085 fTabConverter = new TabConverter();
1086 configureTabConverter();
1087 fTabConverter.setNumberOfSpacesPerTab(getTabSize());
1088 AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
1089 asv.addTextConverter(fTabConverter);
1090 // http://dev.eclipse.org/bugs/show_bug.cgi?id=19270
1091 asv.updateIndentationPrefixes();
1095 private void stopTabConversion() {
1096 if (fTabConverter != null) {
1097 AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
1098 asv.removeTextConverter(fTabConverter);
1099 // http://dev.eclipse.org/bugs/show_bug.cgi?id=19270
1100 asv.updateIndentationPrefixes();
1101 fTabConverter = null;
1105 private boolean isTabConversionEnabled() {
1106 IPreferenceStore store = getPreferenceStore();
1107 return store.getBoolean(SPACES_FOR_TABS);
1110 private void showOverviewRuler() {
1111 AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
1112 asv.showOverviewRuler();
1114 OverviewRuler overviewRuler = asv.getOverviewRuler();
1115 if (overviewRuler != null) {
1116 for (int i = 0; i < ANNOTATION_LAYERS.length; i++) {
1117 AnnotationType type = ANNOTATION_LAYERS[i];
1118 overviewRuler.setLayer(type, i);
1119 if (isAnnotationIndicationInOverviewRulerEnabled(type))
1120 showAnnotationIndicationInOverviewRuler(type, true);
1125 private void hideOverviewRuler() {
1126 AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
1127 asv.hideOverviewRuler();
1130 private boolean isOverviewRulerVisible() {
1131 IPreferenceStore store = getPreferenceStore();
1132 return store.getBoolean(OVERVIEW_RULER);
1135 private Color getColor(String key) {
1136 RGB rgb = PreferenceConverter.getColor(getPreferenceStore(), key);
1137 return getColor(rgb);
1140 private Color getColor(RGB rgb) {
1141 // JavaTextTools textTools = JavaPlugin.getDefault().getJavaTextTools();
1142 // return textTools.getColorManager().getColor(rgb);
1143 return PHPEditorEnvironment.getPHPColorProvider().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);