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() {
839 public void createPartControl(Composite parent) {
840 super.createPartControl(parent);
842 fPaintManager = new PaintManager(getSourceViewer());
844 LinePainter linePainter;
845 linePainter = new LinePainter(getSourceViewer());
847 linePainter.setHighlightColor(
848 new Color(Display.getCurrent(), 225, 235, 224));
850 fPaintManager.addPainter(linePainter);
853 if (isBracketHighlightingEnabled())
854 startBracketHighlighting();
855 if (isLineHighlightingEnabled())
856 startLineHighlighting();
857 if (isPrintMarginVisible())
861 Iterator e= ANNOTATION_MAP.keySet().iterator();
862 while (e.hasNext()) {
863 AnnotationType type= (AnnotationType) e.next();
864 if (isAnnotationIndicationEnabled(type))
865 startAnnotationIndication(type);
868 if (isTabConversionEnabled())
869 startTabConversion();
871 if (isOverviewRulerVisible())
875 Preferences preferences= PHPeclipsePlugin.getDefault().getPluginPreferences();
876 preferences.addPropertyChangeListener(fPropertyChangeListener);
878 IPreferenceStore preferenceStore= getPreferenceStore();
879 boolean closeBrackets= preferenceStore.getBoolean(CLOSE_BRACKETS);
880 boolean closeStrings= preferenceStore.getBoolean(CLOSE_STRINGS);
882 fBracketInserter.setCloseBracketsEnabled(closeBrackets);
883 fBracketInserter.setCloseStringsEnabled(closeStrings);
885 ISourceViewer sourceViewer= getSourceViewer();
886 if (sourceViewer instanceof ITextViewerExtension)
887 ((ITextViewerExtension) sourceViewer).prependVerifyKeyListener(fBracketInserter);
891 private static char getPeerCharacter(char character) {
909 throw new IllegalArgumentException();
914 * @see AbstractTextEditor#doSetInput(IEditorInput)
916 protected void doSetInput(IEditorInput input) throws CoreException {
917 super.doSetInput(input);
918 configureTabConverter();
921 private void startBracketHighlighting() {
922 if (fBracketPainter == null) {
923 ISourceViewer sourceViewer = getSourceViewer();
924 fBracketPainter = new BracketPainter(sourceViewer);
925 fBracketPainter.setHighlightColor(getColor(MATCHING_BRACKETS_COLOR));
926 fPaintManager.addPainter(fBracketPainter);
930 private void stopBracketHighlighting() {
931 if (fBracketPainter != null) {
932 fPaintManager.removePainter(fBracketPainter);
933 fBracketPainter.deactivate(true);
934 fBracketPainter.dispose();
935 fBracketPainter = null;
939 private boolean isBracketHighlightingEnabled() {
940 IPreferenceStore store = getPreferenceStore();
941 return store.getBoolean(MATCHING_BRACKETS);
944 private void startLineHighlighting() {
945 if (fLinePainter == null) {
946 ISourceViewer sourceViewer = getSourceViewer();
947 fLinePainter = new LinePainter(sourceViewer);
948 fLinePainter.setHighlightColor(getColor(CURRENT_LINE_COLOR));
949 fPaintManager.addPainter(fLinePainter);
953 private void stopLineHighlighting() {
954 if (fLinePainter != null) {
955 fPaintManager.removePainter(fLinePainter);
956 fLinePainter.deactivate(true);
957 fLinePainter.dispose();
962 private boolean isLineHighlightingEnabled() {
963 IPreferenceStore store = getPreferenceStore();
964 return store.getBoolean(CURRENT_LINE);
967 private void showPrintMargin() {
968 if (fPrintMarginPainter == null) {
969 fPrintMarginPainter = new PrintMarginPainter(getSourceViewer());
970 fPrintMarginPainter.setMarginRulerColor(getColor(PRINT_MARGIN_COLOR));
971 fPrintMarginPainter.setMarginRulerColumn(
972 getPreferenceStore().getInt(PRINT_MARGIN_COLUMN));
973 fPaintManager.addPainter(fPrintMarginPainter);
977 private void hidePrintMargin() {
978 if (fPrintMarginPainter != null) {
979 fPaintManager.removePainter(fPrintMarginPainter);
980 fPrintMarginPainter.deactivate(true);
981 fPrintMarginPainter.dispose();
982 fPrintMarginPainter = null;
986 private boolean isPrintMarginVisible() {
987 IPreferenceStore store = getPreferenceStore();
988 return store.getBoolean(PRINT_MARGIN);
991 private void startAnnotationIndication(AnnotationType annotationType) {
992 if (fProblemPainter == null) {
993 fProblemPainter = new ProblemPainter(this, getSourceViewer());
994 fPaintManager.addPainter(fProblemPainter);
996 fProblemPainter.setColor(annotationType, getColor(annotationType));
997 fProblemPainter.paintAnnotations(annotationType, true);
998 fProblemPainter.paint(IPainter.CONFIGURATION);
1001 private void shutdownAnnotationIndication() {
1002 if (fProblemPainter != null) {
1004 if (!fProblemPainter.isPaintingAnnotations()) {
1005 fPaintManager.removePainter(fProblemPainter);
1006 fProblemPainter.deactivate(true);
1007 fProblemPainter.dispose();
1008 fProblemPainter = null;
1010 fProblemPainter.paint(IPainter.CONFIGURATION);
1015 private void stopAnnotationIndication(AnnotationType annotationType) {
1016 if (fProblemPainter != null) {
1017 fProblemPainter.paintAnnotations(annotationType, false);
1018 shutdownAnnotationIndication();
1022 private boolean isAnnotationIndicationEnabled(AnnotationType annotationType) {
1023 IPreferenceStore store = getPreferenceStore();
1024 AnnotationInfo info = (AnnotationInfo) ANNOTATION_MAP.get(annotationType);
1026 return store.getBoolean(info.fEditorPreference);
1030 private boolean isAnnotationIndicationInOverviewRulerEnabled(AnnotationType annotationType) {
1031 IPreferenceStore store = getPreferenceStore();
1032 AnnotationInfo info = (AnnotationInfo) ANNOTATION_MAP.get(annotationType);
1034 return store.getBoolean(info.fOverviewRulerPreference);
1038 private void showAnnotationIndicationInOverviewRuler(
1039 AnnotationType annotationType,
1041 AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
1042 OverviewRuler ruler = asv.getOverviewRuler();
1043 if (ruler != null) {
1044 ruler.setColor(annotationType, getColor(annotationType));
1045 ruler.showAnnotation(annotationType, show);
1050 private void setColorInOverviewRuler(
1051 AnnotationType annotationType,
1053 AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
1054 OverviewRuler ruler = asv.getOverviewRuler();
1055 if (ruler != null) {
1056 ruler.setColor(annotationType, color);
1061 private void configureTabConverter() {
1062 if (fTabConverter != null) {
1063 IDocumentProvider provider = getDocumentProvider();
1064 if (provider instanceof PHPDocumentProvider) {
1065 PHPDocumentProvider cup = (PHPDocumentProvider) provider;
1066 fTabConverter.setLineTracker(cup.createLineTracker(getEditorInput()));
1071 private int getTabSize() {
1072 Preferences preferences =
1073 PHPeclipsePlugin.getDefault().getPluginPreferences();
1074 return preferences.getInt(CODE_FORMATTER_TAB_SIZE);
1077 private void startTabConversion() {
1078 if (fTabConverter == null) {
1079 fTabConverter = new TabConverter();
1080 configureTabConverter();
1081 fTabConverter.setNumberOfSpacesPerTab(getTabSize());
1082 AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
1083 asv.addTextConverter(fTabConverter);
1084 // http://dev.eclipse.org/bugs/show_bug.cgi?id=19270
1085 asv.updateIndentationPrefixes();
1089 private void stopTabConversion() {
1090 if (fTabConverter != null) {
1091 AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
1092 asv.removeTextConverter(fTabConverter);
1093 // http://dev.eclipse.org/bugs/show_bug.cgi?id=19270
1094 asv.updateIndentationPrefixes();
1095 fTabConverter = null;
1099 private boolean isTabConversionEnabled() {
1100 IPreferenceStore store = getPreferenceStore();
1101 return store.getBoolean(SPACES_FOR_TABS);
1104 private void showOverviewRuler() {
1105 AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
1106 asv.showOverviewRuler();
1108 OverviewRuler overviewRuler = asv.getOverviewRuler();
1109 if (overviewRuler != null) {
1110 for (int i = 0; i < ANNOTATION_LAYERS.length; i++) {
1111 AnnotationType type = ANNOTATION_LAYERS[i];
1112 overviewRuler.setLayer(type, i);
1113 if (isAnnotationIndicationInOverviewRulerEnabled(type))
1114 showAnnotationIndicationInOverviewRuler(type, true);
1119 private void hideOverviewRuler() {
1120 AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
1121 asv.hideOverviewRuler();
1124 private boolean isOverviewRulerVisible() {
1125 IPreferenceStore store = getPreferenceStore();
1126 return store.getBoolean(OVERVIEW_RULER);
1129 private Color getColor(String key) {
1130 RGB rgb = PreferenceConverter.getColor(getPreferenceStore(), key);
1131 return getColor(rgb);
1134 private Color getColor(RGB rgb) {
1135 // JavaTextTools textTools = JavaPlugin.getDefault().getJavaTextTools();
1136 // return textTools.getColorManager().getColor(rgb);
1137 return PHPEditorEnvironment.getPHPColorProvider().getColor(rgb);
1140 private Color getColor(AnnotationType annotationType) {
1141 AnnotationInfo info = (AnnotationInfo) ANNOTATION_MAP.get(annotationType);
1143 return getColor(info.fColorPreference);
1147 public void dispose() {
1148 ISourceViewer sourceViewer= getSourceViewer();
1149 if (sourceViewer instanceof ITextViewerExtension)
1150 ((ITextViewerExtension) sourceViewer).removeVerifyKeyListener(fBracketInserter);
1152 if (fPropertyChangeListener != null) {
1153 Preferences preferences= PHPeclipsePlugin.getDefault().getPluginPreferences();
1154 preferences.removePropertyChangeListener(fPropertyChangeListener);
1155 fPropertyChangeListener= null;
1159 // if (fJavaEditorErrorTickUpdater != null) {
1160 // fJavaEditorErrorTickUpdater.dispose();
1161 // fJavaEditorErrorTickUpdater= null;
1164 // if (fSelectionHistory != null)
1165 // fSelectionHistory.dispose();
1167 if (fPaintManager != null) {
1168 fPaintManager.dispose();
1169 fPaintManager = null;
1172 if (fActionGroups != null)
1173 fActionGroups.dispose();
1178 protected AnnotationType getAnnotationType(String preferenceKey) {
1179 Iterator e= ANNOTATION_MAP.keySet().iterator();
1180 while (e.hasNext()) {
1181 AnnotationType type= (AnnotationType) e.next();
1182 AnnotationInfo info= (AnnotationInfo) ANNOTATION_MAP.get(type);
1184 if (preferenceKey.equals(info.fColorPreference) || preferenceKey.equals(info.fEditorPreference) || preferenceKey.equals(info.fOverviewRulerPreference))
1192 * @see AbstractTextEditor#handlePreferenceStoreChanged(PropertyChangeEvent)
1194 protected void handlePreferenceStoreChanged(PropertyChangeEvent event) {
1198 AdaptedSourceViewer asv= (AdaptedSourceViewer) getSourceViewer();
1201 String p= event.getProperty();
1203 if (CLOSE_BRACKETS.equals(p)) {
1204 fBracketInserter.setCloseBracketsEnabled(getPreferenceStore().getBoolean(p));
1208 if (CLOSE_STRINGS.equals(p)) {
1209 fBracketInserter.setCloseStringsEnabled(getPreferenceStore().getBoolean(p));
1213 if (SPACES_FOR_TABS.equals(p)) {
1214 if (isTabConversionEnabled())
1215 startTabConversion();
1217 stopTabConversion();
1221 if (MATCHING_BRACKETS.equals(p)) {
1222 if (isBracketHighlightingEnabled())
1223 startBracketHighlighting();
1225 stopBracketHighlighting();
1229 if (MATCHING_BRACKETS_COLOR.equals(p)) {
1230 if (fBracketPainter != null)
1231 fBracketPainter.setHighlightColor(getColor(MATCHING_BRACKETS_COLOR));
1235 if (CURRENT_LINE.equals(p)) {
1236 if (isLineHighlightingEnabled())
1237 startLineHighlighting();
1239 stopLineHighlighting();
1243 if (CURRENT_LINE_COLOR.equals(p)) {
1244 if (fLinePainter != null) {
1245 stopLineHighlighting();
1246 startLineHighlighting();
1251 if (PRINT_MARGIN.equals(p)) {
1252 if (isPrintMarginVisible())
1259 if (PRINT_MARGIN_COLOR.equals(p)) {
1260 if (fPrintMarginPainter != null)
1261 fPrintMarginPainter.setMarginRulerColor(getColor(PRINT_MARGIN_COLOR));
1265 if (PRINT_MARGIN_COLUMN.equals(p)) {
1266 if (fPrintMarginPainter != null)
1267 fPrintMarginPainter.setMarginRulerColumn(getPreferenceStore().getInt(PRINT_MARGIN_COLUMN));
1271 if (OVERVIEW_RULER.equals(p)) {
1272 if (isOverviewRulerVisible())
1273 showOverviewRuler();
1275 hideOverviewRuler();
1279 AnnotationType type= getAnnotationType(p);
1282 AnnotationInfo info= (AnnotationInfo) ANNOTATION_MAP.get(type);
1283 if (info.fColorPreference.equals(p)) {
1284 Color color= getColor(type);
1285 if (fProblemPainter != null) {
1286 fProblemPainter.setColor(type, color);
1287 fProblemPainter.paint(IPainter.CONFIGURATION);
1289 setColorInOverviewRuler(type, color);
1293 if (info.fEditorPreference.equals(p)) {
1294 if (isAnnotationIndicationEnabled(type))
1295 startAnnotationIndication(type);
1297 stopAnnotationIndication(type);
1301 if (info.fOverviewRulerPreference.equals(p)) {
1302 if (isAnnotationIndicationInOverviewRulerEnabled(type))
1303 showAnnotationIndicationInOverviewRuler(type, true);
1305 showAnnotationIndicationInOverviewRuler(type, false);
1310 // IContentAssistant c= asv.getContentAssistant();
1311 // if (c instanceof ContentAssistant)
1312 // ContentAssistPreference.changeConfiguration((ContentAssistant) c, getPreferenceStore(), event);
1316 super.handlePreferenceStoreChanged(event);
1321 * Handles a property change event describing a change
1322 * of the php core's preferences and updates the preference
1323 * related editor properties.
1325 * @param event the property change event
1327 protected void handlePreferencePropertyChanged(org.eclipse.core.runtime.Preferences.PropertyChangeEvent event) {
1328 AdaptedSourceViewer asv= (AdaptedSourceViewer) getSourceViewer();
1330 String p= event.getProperty();
1331 if (CODE_FORMATTER_TAB_SIZE.equals(p)) {
1332 asv.updateIndentationPrefixes();
1333 if (fTabConverter != null)
1334 fTabConverter.setNumberOfSpacesPerTab(getTabSize());
1340 * @see PHPEditor#createJavaSourceViewer(Composite, IVerticalRuler, int)
1342 protected ISourceViewer createJavaSourceViewer(Composite parent, IVerticalRuler ruler, int styles) {
1343 return new AdaptedSourceViewer(parent, ruler, styles);
1346 private boolean isValidSelection(int offset, int length) {
1347 IDocumentProvider provider= getDocumentProvider();
1348 if (provider != null) {
1349 IDocument document= provider.getDocument(getEditorInput());
1350 if (document != null) {
1351 int end= offset + length;
1352 int documentLength= document.getLength();
1353 return 0 <= offset && offset <= documentLength && 0 <= end && end <= documentLength;
1360 * @see AbstractTextEditor#canHandleMove(IEditorInput, IEditorInput)
1362 protected boolean canHandleMove(IEditorInput originalElement, IEditorInput movedElement) {
1364 String oldExtension= ""; //$NON-NLS-1$
1365 if (originalElement instanceof IFileEditorInput) {
1366 IFile file= ((IFileEditorInput) originalElement).getFile();
1368 String ext= file.getFileExtension();
1374 String newExtension= ""; //$NON-NLS-1$
1375 if (movedElement instanceof IFileEditorInput) {
1376 IFile file= ((IFileEditorInput) movedElement).getFile();
1378 newExtension= file.getFileExtension();
1381 return oldExtension.equals(newExtension);