001: /*******************************************************************************
002: * Copyright (c) 2003, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.pde.internal.ui.editor;
011:
012: import java.util.ResourceBundle;
013:
014: import org.eclipse.pde.core.IBaseModel;
015: import org.eclipse.pde.internal.core.text.AbstractEditingModel;
016: import org.eclipse.pde.internal.core.text.IDocumentAttributeNode;
017: import org.eclipse.pde.internal.core.text.IDocumentElementNode;
018: import org.eclipse.pde.internal.core.text.IDocumentRange;
019: import org.eclipse.pde.internal.core.text.IDocumentTextNode;
020: import org.eclipse.pde.internal.core.text.IEditingModel;
021: import org.eclipse.pde.internal.ui.IHelpContextIds;
022: import org.eclipse.pde.internal.ui.PDEPlugin;
023: import org.eclipse.pde.internal.ui.PDEPluginImages;
024: import org.eclipse.pde.internal.ui.PDEUIMessages;
025: import org.eclipse.pde.internal.ui.editor.actions.FormatAction;
026: import org.eclipse.pde.internal.ui.editor.actions.HyperlinkAction;
027: import org.eclipse.pde.internal.ui.editor.actions.PDEActionConstants;
028: import org.eclipse.pde.internal.ui.editor.context.InputContext;
029: import org.eclipse.pde.internal.ui.editor.outline.IOutlineContentCreator;
030: import org.eclipse.pde.internal.ui.editor.outline.IOutlineSelectionHandler;
031: import org.eclipse.pde.internal.ui.editor.plugin.ExtensionHyperLink;
032: import org.eclipse.pde.internal.ui.editor.text.PDESelectAnnotationRulerAction;
033:
034: import org.eclipse.swt.SWT;
035: import org.eclipse.swt.widgets.Composite;
036: import org.eclipse.swt.widgets.Control;
037:
038: import org.eclipse.core.runtime.CoreException;
039:
040: import org.eclipse.core.resources.IMarker;
041:
042: import org.eclipse.jdt.ui.JavaUI;
043: import org.eclipse.jface.action.IAction;
044: import org.eclipse.jface.action.IMenuManager;
045: import org.eclipse.jface.preference.IPreferenceStore;
046: import org.eclipse.jface.viewers.ILabelProvider;
047: import org.eclipse.jface.viewers.IPostSelectionProvider;
048: import org.eclipse.jface.viewers.ISelection;
049: import org.eclipse.jface.viewers.ISelectionChangedListener;
050: import org.eclipse.jface.viewers.ISelectionProvider;
051: import org.eclipse.jface.viewers.IStructuredSelection;
052: import org.eclipse.jface.viewers.ITreeContentProvider;
053: import org.eclipse.jface.viewers.SelectionChangedEvent;
054: import org.eclipse.jface.viewers.StructuredSelection;
055: import org.eclipse.jface.viewers.ViewerComparator;
056:
057: import org.eclipse.jface.text.IDocument;
058: import org.eclipse.jface.text.ITextSelection;
059: import org.eclipse.jface.text.source.ISourceViewer;
060:
061: import org.eclipse.ui.editors.text.EditorsUI;
062: import org.eclipse.ui.editors.text.TextEditor;
063:
064: import org.eclipse.ui.IFileEditorInput;
065: import org.eclipse.ui.IPageLayout;
066: import org.eclipse.ui.PlatformUI;
067: import org.eclipse.ui.forms.IManagedForm;
068: import org.eclipse.ui.forms.editor.FormEditor;
069: import org.eclipse.ui.forms.editor.IFormPage;
070: import org.eclipse.ui.ide.IDE;
071: import org.eclipse.ui.ide.IGotoMarker;
072: import org.eclipse.ui.part.IShowInTargetList;
073: import org.eclipse.ui.texteditor.ChainedPreferenceStore;
074: import org.eclipse.ui.texteditor.ContentAssistAction;
075: import org.eclipse.ui.texteditor.DefaultRangeIndicator;
076: import org.eclipse.ui.texteditor.ITextEditorActionConstants;
077: import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
078: import org.eclipse.ui.texteditor.ResourceAction;
079: import org.eclipse.ui.texteditor.TextOperationAction;
080:
081: public abstract class PDESourcePage extends TextEditor implements
082: IFormPage, IGotoMarker, ISelectionChangedListener,
083: IOutlineContentCreator, IOutlineSelectionHandler {
084:
085: private static String RES_BUNDLE_LOCATION = "org.eclipse.pde.internal.ui.editor.text.ConstructedPDEEditorMessages"; //$NON-NLS-1$
086: private static ResourceBundle fgBundleForConstructedKeys = ResourceBundle
087: .getBundle(RES_BUNDLE_LOCATION);
088:
089: public static ResourceBundle getBundleForConstructedKeys() {
090: return fgBundleForConstructedKeys;
091: }
092:
093: /* (non-Javadoc)
094: * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#initializeKeyBindingScopes()
095: */
096: protected void initializeKeyBindingScopes() {
097: setKeyBindingScopes(new String[] { "org.eclipse.pde.ui.pdeEditorContext" }); //$NON-NLS-1$
098: }
099:
100: /**
101: * Updates the OutlinePage selection and this editor's range indicator.
102: *
103: * @since 3.0
104: */
105: private class PDESourcePageChangedListener implements
106: ISelectionChangedListener {
107:
108: /**
109: * Installs this selection changed listener with the given selection
110: * provider. If the selection provider is a post selection provider,
111: * post selection changed events are the preferred choice, otherwise
112: * normal selection changed events are requested.
113: *
114: * @param selectionProvider
115: */
116: public void install(ISelectionProvider selectionProvider) {
117: if (selectionProvider != null) {
118: if (selectionProvider instanceof IPostSelectionProvider) {
119: IPostSelectionProvider provider = (IPostSelectionProvider) selectionProvider;
120: provider.addPostSelectionChangedListener(this );
121: } else {
122: selectionProvider.addSelectionChangedListener(this );
123: }
124: }
125: }
126:
127: /*
128: * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
129: */
130: public void selectionChanged(SelectionChangedEvent event) {
131: handleSelectionChangedSourcePage(event);
132: }
133:
134: /**
135: * Removes this selection changed listener from the given selection
136: * provider.
137: *
138: * @param selectionProviderstyle
139: */
140: public void uninstall(ISelectionProvider selectionProvider) {
141: if (selectionProvider != null) {
142: if (selectionProvider instanceof IPostSelectionProvider) {
143: IPostSelectionProvider provider = (IPostSelectionProvider) selectionProvider;
144: provider.removePostSelectionChangedListener(this );
145: } else {
146: selectionProvider
147: .removeSelectionChangedListener(this );
148: }
149: }
150: }
151:
152: }
153:
154: /**
155: * The editor selection changed listener.
156: *
157: * @since 3.0
158: */
159: private PDESourcePageChangedListener fEditorSelectionChangedListener;
160: private PDEFormEditor fEditor;
161: private Control fControl;
162: private int fIndex;
163: private String fId;
164: private InputContext fInputContext;
165: private ISortableContentOutlinePage fOutlinePage;
166: private ISelectionChangedListener fOutlineSelectionChangedListener;
167: protected Object fSelection;
168:
169: public PDESourcePage(PDEFormEditor editor, String id, String title) {
170: fId = id;
171: initialize(editor);
172: IPreferenceStore[] stores = new IPreferenceStore[2];
173: stores[0] = PDEPlugin.getDefault().getPreferenceStore();
174: stores[1] = EditorsUI.getPreferenceStore();
175: setPreferenceStore(new ChainedPreferenceStore(stores));
176: setRangeIndicator(new DefaultRangeIndicator());
177: if (isSelectionListener())
178: getEditor().getSite().getSelectionProvider()
179: .addSelectionChangedListener(this );
180: }
181:
182: /* (non-Javadoc)
183: * @see org.eclipse.ui.forms.editor.IFormPage#initialize(org.eclipse.ui.forms.editor.FormEditor)
184: */
185: public void initialize(FormEditor editor) {
186: fEditor = (PDEFormEditor) editor;
187: }
188:
189: public void dispose() {
190: if (fEditorSelectionChangedListener != null) {
191: fEditorSelectionChangedListener
192: .uninstall(getSelectionProvider());
193: fEditorSelectionChangedListener = null;
194: }
195: if (fOutlinePage != null) {
196: fOutlinePage.dispose();
197: fOutlinePage = null;
198: }
199: if (isSelectionListener())
200: getEditor().getSite().getSelectionProvider()
201: .removeSelectionChangedListener(this );
202: super .dispose();
203: }
204:
205: /* (non-Javadoc)
206: * @see org.eclipse.pde.internal.ui.editor.outline.IOutlineContentCreator#createOutlineLabelProvider()
207: */
208: public abstract ILabelProvider createOutlineLabelProvider();
209:
210: /* (non-Javadoc)
211: * @see org.eclipse.pde.internal.ui.editor.outline.IOutlineContentCreator#createOutlineContentProvider()
212: */
213: public abstract ITreeContentProvider createOutlineContentProvider();
214:
215: /* (non-Javadoc)
216: * @see org.eclipse.pde.internal.ui.editor.outline.IOutlineContentCreator#createOutlineComparator()
217: */
218: public abstract ViewerComparator createOutlineComparator();
219:
220: /* (non-Javadoc)
221: * @see org.eclipse.pde.internal.ui.editor.outline.IOutlineSelectionHandler#updateSelection(org.eclipse.jface.viewers.SelectionChangedEvent)
222: */
223: public void updateSelection(SelectionChangedEvent event) {
224: ISelection sel = event.getSelection();
225: if (sel instanceof IStructuredSelection) {
226: IStructuredSelection structuredSelection = (IStructuredSelection) sel;
227: updateSelection(structuredSelection.getFirstElement());
228: }
229: }
230:
231: /* (non-Javadoc)
232: * @see org.eclipse.pde.internal.ui.editor.outline.IOutlineSelectionHandler#updateSelection(java.lang.Object)
233: */
234: public abstract void updateSelection(Object object);
235:
236: /* (non-Javadoc)
237: * @see org.eclipse.pde.internal.ui.editor.outline.IOutlineContentCreator#createDefaultOutlineComparator()
238: */
239: public ViewerComparator createDefaultOutlineComparator() {
240: return null;
241: }
242:
243: protected ISortableContentOutlinePage createOutlinePage() {
244: SourceOutlinePage sourceOutlinePage = new SourceOutlinePage(
245: (IEditingModel) getInputContext().getModel(),
246: createOutlineLabelProvider(),
247: createOutlineContentProvider(),
248: createDefaultOutlineComparator(),
249: createOutlineComparator());
250: fOutlinePage = sourceOutlinePage;
251: fOutlineSelectionChangedListener = new ISelectionChangedListener() {
252: public void selectionChanged(SelectionChangedEvent event) {
253: updateSelection(event);
254: }
255: };
256: fOutlinePage
257: .addSelectionChangedListener(fOutlineSelectionChangedListener);
258: getSelectionProvider().addSelectionChangedListener(
259: sourceOutlinePage);
260: fEditorSelectionChangedListener = new PDESourcePageChangedListener();
261: fEditorSelectionChangedListener.install(getSelectionProvider());
262: return fOutlinePage;
263: }
264:
265: /* (non-Javadoc)
266: * @see org.eclipse.pde.internal.ui.editor.outline.IOutlineSelectionHandler#getContentOutline()
267: */
268: public ISortableContentOutlinePage getContentOutline() {
269: if (fOutlinePage == null)
270: fOutlinePage = createOutlinePage();
271: return fOutlinePage;
272: }
273:
274: /* (non-Javadoc)
275: * @see org.eclipse.ui.forms.editor.IFormPage#getEditor()
276: */
277: public FormEditor getEditor() {
278: return fEditor;
279: }
280:
281: /* (non-Javadoc)
282: * @see org.eclipse.ui.forms.editor.IFormPage#getManagedForm()
283: */
284: public IManagedForm getManagedForm() {
285: // not a form page
286: return null;
287: }
288:
289: protected void firePropertyChange(int type) {
290: if (type == PROP_DIRTY) {
291: fEditor.fireSaveNeeded(getEditorInput(), true);
292: } else
293: super .firePropertyChange(type);
294: }
295:
296: /* (non-Javadoc)
297: * @see org.eclipse.ui.forms.editor.IFormPage#setActive(boolean)
298: */
299: public void setActive(boolean active) {
300: fInputContext.setSourceEditingMode(active);
301: // Update the text selection if this page is being activated
302: if (active) {
303: updateTextSelection();
304: }
305: }
306:
307: public boolean canLeaveThePage() {
308: return true;
309: }
310:
311: /* (non-Javadoc)
312: * @see org.eclipse.ui.forms.editor.IFormPage#isActive()
313: */
314: public boolean isActive() {
315: return this .equals(fEditor.getActivePageInstance());
316: }
317:
318: public void createPartControl(Composite parent) {
319: super .createPartControl(parent);
320: Control[] children = parent.getChildren();
321: fControl = children[children.length - 1];
322:
323: PlatformUI.getWorkbench().getHelpSystem().setHelp(fControl,
324: IHelpContextIds.MANIFEST_SOURCE_PAGE);
325: }
326:
327: /* (non-Javadoc)
328: * @see org.eclipse.ui.forms.editor.IFormPage#getPartControl()
329: */
330: public Control getPartControl() {
331: return fControl;
332: }
333:
334: /* (non-Javadoc)
335: * @see org.eclipse.ui.forms.editor.IFormPage#getId()
336: */
337: public String getId() {
338: return fId;
339: }
340:
341: /* (non-Javadoc)
342: * @see org.eclipse.ui.forms.editor.IFormPage#getIndex()
343: */
344: public int getIndex() {
345: return fIndex;
346: }
347:
348: /* (non-Javadoc)
349: * @see org.eclipse.ui.forms.editor.IFormPage#setIndex(int)
350: */
351: public void setIndex(int index) {
352: fIndex = index;
353: }
354:
355: /* (non-Javadoc)
356: * @see org.eclipse.ui.forms.editor.IFormPage#isSource()
357: */
358: public boolean isEditor() {
359: return true;
360: }
361:
362: /**
363: * @return Returns the inputContext.
364: */
365: public InputContext getInputContext() {
366: return fInputContext;
367: }
368:
369: /**
370: * @param inputContext The inputContext to set.
371: */
372: public void setInputContext(InputContext inputContext) {
373: fInputContext = inputContext;
374: setDocumentProvider(inputContext.getDocumentProvider());
375: }
376:
377: /* (non-Javadoc)
378: * @see org.eclipse.ui.forms.editor.IFormPage#focusOn(java.lang.Object)
379: */
380: public boolean selectReveal(Object object) {
381: if (object instanceof IMarker) {
382: IDE.gotoMarker(this , (IMarker) object);
383: return true;
384: }
385: return false;
386: }
387:
388: public IDocumentRange getRangeElement(int offset,
389: boolean searchChildren) {
390: return null;
391: }
392:
393: public void setHighlightRange(IDocumentRange range,
394: boolean moveCursor) {
395: int offset = range.getOffset();
396: if (offset == -1) {
397: resetHighlightRange();
398: return;
399: }
400:
401: ISourceViewer sourceViewer = getSourceViewer();
402: if (sourceViewer == null)
403: return;
404:
405: IDocument document = sourceViewer.getDocument();
406: if (document == null)
407: return;
408:
409: int length = range.getLength();
410: setHighlightRange(offset, length == -1 ? 1 : length, moveCursor);
411: }
412:
413: public void setSelectedRange(IDocumentRange range,
414: boolean fullNodeSelection) {
415: ISourceViewer sourceViewer = getSourceViewer();
416: if (sourceViewer == null)
417: return;
418:
419: IDocument document = sourceViewer.getDocument();
420: if (document == null)
421: return;
422:
423: int offset;
424: int length;
425: if (range instanceof IDocumentElementNode && !fullNodeSelection) {
426: length = ((IDocumentElementNode) range).getXMLTagName()
427: .length();
428: offset = range.getOffset() + 1;
429: } else {
430: length = range.getLength();
431: offset = range.getOffset();
432: }
433: sourceViewer.setSelectedRange(offset, length);
434: }
435:
436: public int getOrientation() {
437: return SWT.LEFT_TO_RIGHT;
438: }
439:
440: protected void createActions() {
441: super .createActions();
442: PDESelectAnnotationRulerAction action = new PDESelectAnnotationRulerAction(
443: getBundleForConstructedKeys(),
444: "PDESelectAnnotationRulerAction.", this , getVerticalRuler()); //$NON-NLS-1$
445: setAction(ITextEditorActionConstants.RULER_CLICK, action);
446: PDEFormEditorContributor contributor = fEditor == null ? null
447: : fEditor.getContributor();
448: if (contributor instanceof PDEFormTextEditorContributor) {
449: PDEFormTextEditorContributor textContributor = (PDEFormTextEditorContributor) contributor;
450: setAction(PDEActionConstants.OPEN, textContributor
451: .getHyperlinkAction());
452: setAction(PDEActionConstants.FORMAT, textContributor
453: .getFormatAction());
454: if (textContributor.supportsContentAssist())
455: createContentAssistAction();
456: }
457:
458: // Create the quick outline action
459: createQuickOutlineAction();
460: }
461:
462: /**
463: *
464: */
465: private void createQuickOutlineAction() {
466: // Quick Outline Action
467: ResourceAction action = new TextOperationAction(
468: getBundleForConstructedKeys(), "QuickOutline.", this , //$NON-NLS-1$
469: PDEProjectionViewer.QUICK_OUTLINE, true);
470: action
471: .setActionDefinitionId(PDEActionConstants.COMMAND_ID_QUICK_OUTLINE);
472: action
473: .setText(PDEUIMessages.PDESourcePage_actionTextQuickOutline);
474: action.setId(PDEActionConstants.COMMAND_ID_QUICK_OUTLINE);
475: action.setImageDescriptor(PDEPluginImages.DESC_OVERVIEW_OBJ);
476: setAction(PDEActionConstants.COMMAND_ID_QUICK_OUTLINE, action);
477: }
478:
479: private void createContentAssistAction() {
480: IAction contentAssist = new ContentAssistAction(
481: getBundleForConstructedKeys(),
482: "ContentAssistProposal.", this ); //$NON-NLS-1$
483: contentAssist
484: .setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
485: setAction("ContentAssist", contentAssist); //$NON-NLS-1$
486: markAsStateDependentAction("ContentAssist", true); //$NON-NLS-1$
487: }
488:
489: public final void selectionChanged(SelectionChangedEvent event) {
490: if (event.getSource() == getSelectionProvider())
491: return;
492: ISelection sel = event.getSelection();
493: if (sel instanceof ITextSelection)
494: return;
495: if (sel instanceof IStructuredSelection)
496: fSelection = ((IStructuredSelection) sel).getFirstElement();
497: else
498: fSelection = null;
499: }
500:
501: /*
502: * Locate an IDocumentRange, subclasses that want to
503: * highlight text components based on site selection
504: * should override this method.
505: */
506: protected IDocumentRange findRange() {
507: return null;
508: }
509:
510: public void updateTextSelection() {
511: IDocumentRange range = findRange();
512: if (range == null)
513: return;
514: IBaseModel model = getInputContext().getModel();
515: if (!(model instanceof AbstractEditingModel))
516: return;
517:
518: if (range.getOffset() == -1 || isDirty()) {
519: try {
520: ((AbstractEditingModel) model)
521: .adjustOffsets(((AbstractEditingModel) model)
522: .getDocument());
523: } catch (CoreException e) {
524: }
525: range = findRange();
526: }
527: setHighlightRange(range, true);
528: setSelectedRange(range, false);
529: }
530:
531: /*
532: * Subclasses that wish to provide PDEFormPage -> PDESourcePage
533: * selection persistence should override this and return true.
534: */
535: protected boolean isSelectionListener() {
536: return false;
537: }
538:
539: public ISourceViewer getViewer() {
540: return getSourceViewer();
541: }
542:
543: protected void editorContextMenuAboutToShow(IMenuManager menu) {
544: PDEFormEditorContributor contributor = fEditor == null ? null
545: : fEditor.getContributor();
546: if (contributor instanceof PDEFormTextEditorContributor) {
547: PDEFormTextEditorContributor textContributor = (PDEFormTextEditorContributor) contributor;
548: HyperlinkAction action = textContributor
549: .getHyperlinkAction();
550: if ((action != null)
551: && action.isEnabled()
552: && ((action.getHyperLink() instanceof ExtensionHyperLink) == false)) {
553: // Another detector handles this the extension hyperlink case
554: // org.eclipse.pde.internal.ui.editor.plugin.ExtensionAttributePointDectector.java
555: // Implemented at a higher level. As a result, need to disable
556: // the action here to prevent duplicate entries in the context menu
557: menu.add(action);
558: }
559: FormatAction formatManifestAction = textContributor
560: .getFormatAction();
561: if (isEditable() && formatManifestAction != null
562: && formatManifestAction.isEnabled())
563: menu.add(formatManifestAction);
564: }
565: super .editorContextMenuAboutToShow(menu);
566: }
567:
568: /**
569: * @return
570: */
571: public Object getSelection() {
572: return fSelection;
573: }
574:
575: // TODO: MP: QO: LOW: Create method to set selection and make fSelection private
576:
577: /* (non-Javadoc)
578: * @see org.eclipse.pde.internal.ui.editor.outline.IOutlineContentCreator#getOutlineInput()
579: */
580: public Object getOutlineInput() {
581: return getInputContext().getModel();
582: }
583:
584: /**
585: * @param rangeElement
586: */
587: protected void updateOutlinePageSelection(Object rangeElement) {
588: // Set selection in source outline page if the 'Link with Editor'
589: // feature is on
590: if (PDEPlugin.getDefault().getPreferenceStore().getBoolean(
591: "ToggleLinkWithEditorAction.isChecked")) { //$NON-NLS-1$
592: // Ensure we have a source outline page
593: if ((fOutlinePage instanceof SourceOutlinePage) == false) {
594: return;
595: }
596: SourceOutlinePage outlinePage = (SourceOutlinePage) fOutlinePage;
597: // Temporarily remove the listener to prevent a selection event being fired
598: // back at this page
599: outlinePage.removeAllSelectionChangedListeners();
600: if (rangeElement != null) {
601: outlinePage.setSelection(new StructuredSelection(
602: rangeElement));
603: } else {
604: outlinePage.setSelection(StructuredSelection.EMPTY);
605: }
606: outlinePage.addAllSelectionChangedListeners();
607: }
608: }
609:
610: /**
611: * @param event
612: */
613: protected void handleSelectionChangedSourcePage(
614: SelectionChangedEvent event) {
615: ISelection selection = event.getSelection();
616: if (!selection.isEmpty() && selection instanceof ITextSelection) {
617: synchronizeOutlinePage(((ITextSelection) selection)
618: .getOffset());
619: }
620: }
621:
622: /**
623: * @param rangeElement
624: */
625: protected void updateHighlightRange(IDocumentRange rangeElement) {
626: if (rangeElement != null) {
627: setHighlightRange(rangeElement, false);
628: } else {
629: resetHighlightRange();
630: }
631: }
632:
633: /**
634: * @param offset
635: */
636: protected void synchronizeOutlinePage(int offset) {
637: IDocumentRange rangeElement = getRangeElement(offset, false);
638: updateHighlightRange(rangeElement);
639: updateOutlinePageSelection(rangeElement);
640: }
641:
642: /**
643: * Triggered by toggling the 'Link with Editor' button in the outline
644: * view
645: * @param offset
646: */
647: public void synchronizeOutlinePage() {
648: // Get the current position of the cursor in this page
649: int current_offset = getSourceViewer().getSelectedRange().x;
650: synchronizeOutlinePage(current_offset);
651: }
652:
653: /**
654: * Utility method for getRangeElement(int, boolean)
655: * @param node
656: * @param offset
657: * @param searchChildren
658: * @see org.eclipse.pde.internal.ui.editor.PDESourcePage.findNode(Object[], int, boolean)
659: * @return
660: */
661: protected IDocumentRange findNode(IDocumentElementNode node,
662: int offset, boolean searchChildren) {
663: return findNode(new Object[] { node }, offset, searchChildren);
664: }
665:
666: /**
667: * Utility method for getRangeElement(int, boolean)
668: * @param nodes All entries should be instances of IDocumentElementNode
669: * @param offset The offset the cursor is currently on in the document
670: * @param searchChildren <code>true</code> to search child nodes; <code>false</code> otherwise.
671: * @return Node the offset is in
672: */
673: protected IDocumentRange findNode(Object[] nodes, int offset,
674: boolean searchChildren) {
675: for (int i = 0; i < nodes.length; i++) {
676: IDocumentElementNode node = (IDocumentElementNode) nodes[i];
677: if (node.getOffset() <= offset
678: && offset < node.getOffset() + node.getLength()) {
679:
680: if (!searchChildren)
681: return node;
682:
683: if (node.getOffset() < offset
684: && offset <= node.getOffset()
685: + node.getXMLTagName().length() + 1)
686: return node;
687:
688: IDocumentAttributeNode[] attrs = node
689: .getNodeAttributes();
690: if (attrs != null)
691: for (int a = 0; a < attrs.length; a++)
692: if (attrs[a].getNameOffset() <= offset
693: && offset <= attrs[a].getValueOffset()
694: + attrs[a].getValueLength())
695: return attrs[a];
696:
697: IDocumentTextNode textNode = node.getTextNode();
698: if (textNode != null
699: && textNode.getOffset() <= offset
700: && offset < textNode.getOffset()
701: + textNode.getLength())
702: return textNode;
703:
704: IDocumentElementNode[] children = node.getChildNodes();
705: if (children != null)
706: for (int c = 0; c < children.length; c++)
707: if (children[c].getOffset() <= offset
708: && offset < children[c].getOffset()
709: + children[c].getLength())
710: return findNode(children[c], offset,
711: searchChildren);
712:
713: // not contained inside any sub elements, must be inside node
714: return node;
715: }
716: }
717: return null;
718: }
719:
720: /**
721: * Override the getAdapter function to return a list of targets
722: * for the "Show In >" action in the context menu.
723: *
724: * @param adapter
725: * @return A list of targets (IShowInTargetList) for the "Show In >"
726: * submenu if the appropriate adapter is passed in and the editor
727: * is not read-only. Returns <code>super.getAdapter(adapter)</code>
728: * otherwise.
729: */
730: public Object getAdapter(Class adapter) {
731: if ((adapter == IShowInTargetList.class)
732: && (fEditor != null)
733: && (fEditor.getEditorInput() instanceof IFileEditorInput)) {
734: return getShowInTargetList();
735: }
736: return super .getAdapter(adapter);
737: }
738:
739: /**
740: * Returns the <code>IShowInTargetList</code> for this view.
741: * @return the <code>IShowInTargetList</code>
742: */
743: protected IShowInTargetList getShowInTargetList() {
744: return new IShowInTargetList() {
745: public String[] getShowInTargetIds() {
746: return new String[] { JavaUI.ID_PACKAGES,
747: IPageLayout.ID_RES_NAV };
748: }
749: };
750: }
751:
752: /**
753: * @param range
754: * @return
755: */
756: public IDocumentRange adaptRange(IDocumentRange range) {
757: // Subclasses to override
758: return range;
759: }
760:
761: }
|