001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 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.ui.internal.texteditor.quickdiff;
011:
012: import org.eclipse.core.runtime.Assert;
013:
014: import org.eclipse.jface.action.Action;
015:
016: import org.eclipse.jface.text.source.IAnnotationModel;
017: import org.eclipse.jface.text.source.IAnnotationModelExtension;
018: import org.eclipse.jface.text.source.IChangeRulerColumn;
019:
020: import org.eclipse.ui.IEditorInput;
021: import org.eclipse.ui.texteditor.quickdiff.IQuickDiffReferenceProvider;
022: import org.eclipse.ui.texteditor.quickdiff.ReferenceProviderDescriptor;
023: import org.eclipse.ui.texteditor.IDocumentProvider;
024: import org.eclipse.ui.texteditor.ITextEditor;
025: import org.eclipse.ui.texteditor.ITextEditorExtension3;
026: import org.eclipse.ui.texteditor.IUpdate;
027:
028: /**
029: * Action to set the quick diff reference for the document displayed in the editor. An instance of
030: * this class is created for every extension to the extension point <code>quickdiff.referenceprovider</code>, and for
031: * every editor. It acts as a proxy; its <code>run</code> method installs the reference provider
032: * specified by the extension with the quick diff differ on the current document.
033: *
034: * @since 3.0
035: */
036: public class ReferenceSelectionAction extends Action implements IUpdate {
037:
038: /** The editor we get the document from. */
039: private ITextEditor fEditor = null;
040: /** The descriptor of the managed extension. */
041: private final ReferenceProviderDescriptor fDescriptor;
042: /** The implementation of the extension, after it has been loaded. */
043: private IQuickDiffReferenceProvider fProvider;
044:
045: /**
046: * Creates a new instance that will lazily create the implementation provided by the extension.
047: *
048: * @param descriptor describes the extension.
049: * @param editor the editor for which this action is created.
050: */
051: public ReferenceSelectionAction(
052: ReferenceProviderDescriptor descriptor, ITextEditor editor) {
053: super ("", AS_RADIO_BUTTON); //$NON-NLS-1$
054: setChecked(false);
055: setEnabled(true);
056: Assert.isLegal(descriptor != null);
057: fDescriptor = descriptor;
058: fEditor = editor;
059: update();
060: }
061:
062: /**
063: * Creates an instance of the implementation provided by the extension, if none has been created
064: * before. Otherwise, the cached implementation is returned.
065: * @return The <code>IQuickDiffProviderImplementation</code> instance provided by the extension.
066: */
067: private IQuickDiffReferenceProvider getProvider() {
068: if (fProvider == null) {
069: fProvider = fDescriptor.createProvider();
070: }
071: return fProvider;
072: }
073:
074: /*
075: * @see org.eclipse.jface.action.IAction#run()
076: */
077: public void run() {
078:
079: DocumentLineDiffer differ = getDiffer(true); // create if needed, so the user does not have to toggle display when he selects a reference
080: if (differ == null)
081: return;
082:
083: if (fEditor instanceof ITextEditorExtension3) {
084: ITextEditorExtension3 extension = (ITextEditorExtension3) fEditor;
085: IQuickDiffReferenceProvider provider = getProvider();
086: if (provider != null) {
087: provider.setActiveEditor(fEditor);
088: if (provider.isEnabled()) {
089: differ.setReferenceProvider(provider);
090: extension.showChangeInformation(true);
091: setEnabled(true);
092: } else
093: setEnabled(false);
094: }
095: }
096: }
097:
098: /*
099: * @see org.eclipse.ui.texteditor.IUpdate#update()
100: */
101: public void update() {
102: /* two things happen here:
103: * 1: checked state setting - if a provider is already installed, and its id matches
104: * our id, we are in checked state.
105: * 2: enablement - if the extending plugin has been loaded, we check the provider for
106: * enablement and take it as our own.
107: */
108: setText(fDescriptor.getLabel());
109: DocumentLineDiffer differ = getDiffer(false); // don't create it if we're not showing
110: setChecked(false);
111: if (differ != null) {
112: IQuickDiffReferenceProvider provider = differ
113: .getReferenceProvider();
114: if (provider != null
115: && provider.getId().equals(fDescriptor.getId())) {
116: setChecked(true);
117: }
118: }
119:
120: if (fDescriptor.isPluginLoaded()) {
121: getProvider();
122: if (fProvider == null) {
123: setEnabled(false);
124: } else {
125: fProvider.setActiveEditor(fEditor);
126: setEnabled(fProvider.isEnabled());
127: }
128: } else {
129: // optimistically enable it
130: setEnabled(true);
131: }
132: }
133:
134: /**
135: * Fetches the differ installed with the current editor's document's annotation model. If none
136: * is installed yet, and <code>createIfNeeded</code> is true, one is created and attached to the
137: * model.
138: *
139: * @param createIfNeeded when set to <code>true</code>, a new differ will be created if needed.
140: * @return the differ installed with the annotation model, or <code>null</code>.
141: */
142: private DocumentLineDiffer getDiffer(boolean createIfNeeded) {
143: // get annotation model
144: if (fEditor == null)
145: return null;
146:
147: IDocumentProvider provider = fEditor.getDocumentProvider();
148: IEditorInput editorInput = fEditor.getEditorInput();
149: if (provider == null || editorInput == null)
150: return null;
151:
152: IAnnotationModel m = provider.getAnnotationModel(editorInput);
153: IAnnotationModelExtension model = null;
154: if (m instanceof IAnnotationModelExtension) {
155: model = (IAnnotationModelExtension) m;
156: } else {
157: return null;
158: }
159:
160: // get differ
161: DocumentLineDiffer differ = (DocumentLineDiffer) model
162: .getAnnotationModel(IChangeRulerColumn.QUICK_DIFF_MODEL_ID);
163:
164: // create if needed
165: if (differ == null && createIfNeeded) {
166: differ = new DocumentLineDiffer();
167: model.addAnnotationModel(
168: IChangeRulerColumn.QUICK_DIFF_MODEL_ID, differ);
169: }
170:
171: return differ;
172: }
173: }
|