001: /*******************************************************************************
002: * Copyright (c) 2000, 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.ui.texteditor.quickdiff;
011:
012: import java.util.Iterator;
013: import java.util.List;
014:
015: import org.eclipse.jface.action.IAction;
016: import org.eclipse.jface.action.IMenuListener;
017: import org.eclipse.jface.action.IMenuManager;
018: import org.eclipse.jface.action.MenuManager;
019: import org.eclipse.jface.action.Separator;
020: import org.eclipse.jface.viewers.ISelection;
021:
022: import org.eclipse.ui.IEditorActionDelegate;
023: import org.eclipse.ui.IEditorPart;
024: import org.eclipse.ui.IWorkbenchActionConstants;
025: import org.eclipse.ui.texteditor.ITextEditor;
026: import org.eclipse.ui.texteditor.ITextEditorExtension;
027: import org.eclipse.ui.texteditor.ITextEditorExtension3;
028: import org.eclipse.ui.texteditor.IUpdate;
029:
030: import org.eclipse.ui.internal.texteditor.quickdiff.QuickDiffMessages;
031: import org.eclipse.ui.internal.texteditor.quickdiff.QuickDiffRestoreAction;
032: import org.eclipse.ui.internal.texteditor.quickdiff.ReferenceSelectionAction;
033: import org.eclipse.ui.internal.texteditor.quickdiff.RestoreAction;
034: import org.eclipse.ui.internal.texteditor.quickdiff.RevertBlockAction;
035: import org.eclipse.ui.internal.texteditor.quickdiff.RevertLineAction;
036: import org.eclipse.ui.internal.texteditor.quickdiff.RevertSelectionAction;
037:
038: /**
039: * Action to toggle the line number bar's quick diff display. When turned on, quick diff shows
040: * the changes relative to the saved version of the file.
041: *
042: * @since 3.0
043: */
044: public class QuickDiffToggleAction implements IEditorActionDelegate,
045: IUpdate {
046:
047: /** The editor we are working on. */
048: ITextEditor fEditor = null;
049:
050: /** Our UI proxy action. */
051: IAction fProxy;
052:
053: /** The restore actions associated with this toggle action. */
054: QuickDiffRestoreAction[] fRestoreActions = new QuickDiffRestoreAction[] {
055: new RevertSelectionAction(fEditor, true),
056: new RevertBlockAction(fEditor, true),
057: new RevertLineAction(fEditor, true),
058: new RestoreAction(fEditor, true), };
059:
060: /** The menu listener that adds the ruler context menu. */
061: private IMenuListener fListener = new IMenuListener() {
062: /** Group name for additions, in CompilationUnitEditor... */
063: private static final String GROUP_ADD = "add"; //$NON-NLS-1$
064: /** Group name for debug contributions */
065: private static final String GROUP_DEBUB = "debug"; //$NON-NLS-1$
066: private static final String GROUP_QUICKDIFF = "quickdiff"; //$NON-NLS-1$
067: private static final String MENU_ID = "quickdiff.menu"; //$NON-NLS-1$
068: private static final String GROUP_RESTORE = "restore"; //$NON-NLS-1$
069:
070: public void menuAboutToShow(IMenuManager manager) {
071: // update the toggle action itself
072: update();
073:
074: IMenuManager menu = (IMenuManager) manager.find(MENU_ID);
075: // only add menu if it isn't there yet
076: if (menu == null) {
077: /* HACK: pre-install menu groups
078: * This is needed since we get the blank context menu, but want to show up
079: * in the same position as the extension-added QuickDiffToggleAction.
080: * The extension is added at the end (naturally), but other menus (debug, add)
081: * don't add themselves to MB_ADDITIONS or alike, but rather to the end, too. So
082: * we pre-install their respective menu groups here.
083: */
084: if (manager.find(GROUP_DEBUB) == null)
085: manager.insertBefore(
086: IWorkbenchActionConstants.MB_ADDITIONS,
087: new Separator(GROUP_DEBUB));
088: if (manager.find(GROUP_ADD) == null)
089: manager.insertAfter(
090: IWorkbenchActionConstants.MB_ADDITIONS,
091: new Separator(GROUP_ADD));
092: if (manager.find(GROUP_RESTORE) == null)
093: manager.insertAfter(GROUP_ADD, new Separator(
094: GROUP_RESTORE));
095: if (manager.find(GROUP_QUICKDIFF) == null)
096: manager.insertAfter(GROUP_RESTORE, new Separator(
097: GROUP_QUICKDIFF));
098:
099: // create quickdiff menu
100: menu = new MenuManager(
101: QuickDiffMessages.quickdiff_menu_label, MENU_ID);
102: List descriptors = new QuickDiff()
103: .getReferenceProviderDescriptors();
104: for (Iterator it = descriptors.iterator(); it.hasNext();) {
105: ReferenceProviderDescriptor desc = (ReferenceProviderDescriptor) it
106: .next();
107: ReferenceSelectionAction action = new ReferenceSelectionAction(
108: desc, fEditor);
109: if (action.isEnabled())
110: menu.add(action);
111: }
112: manager.appendToGroup(GROUP_QUICKDIFF, menu);
113:
114: // create restore menu if this action is enabled
115: if (isConnected()) {
116: for (int i = 0; i < fRestoreActions.length; i++) {
117: fRestoreActions[i].update();
118: }
119: // only add block action if selection action is not enabled
120: if (fRestoreActions[0].isEnabled())
121: manager.appendToGroup(GROUP_RESTORE,
122: fRestoreActions[0]);
123: else if (fRestoreActions[1].isEnabled())
124: manager.appendToGroup(GROUP_RESTORE,
125: fRestoreActions[1]);
126: if (fRestoreActions[2].isEnabled())
127: manager.appendToGroup(GROUP_RESTORE,
128: fRestoreActions[2]);
129: if (fRestoreActions[3].isEnabled())
130: manager.appendToGroup(GROUP_RESTORE,
131: fRestoreActions[3]);
132: }
133: }
134: }
135: };
136:
137: /*
138: * @see org.eclipse.ui.IEditorActionDelegate#setActiveEditor(org.eclipse.jface.action.IAction, org.eclipse.ui.IEditorPart)
139: */
140: public void setActiveEditor(IAction action, IEditorPart targetEditor) {
141: fProxy = action;
142: removePopupMenu();
143: if (targetEditor instanceof ITextEditor) {
144: fEditor = (ITextEditor) targetEditor;
145: } else
146: fEditor = null;
147: for (int i = 0; i < fRestoreActions.length; i++) {
148: fRestoreActions[i].setEditor(fEditor);
149: }
150: setPopupMenu();
151: }
152:
153: /**
154: * Removes the ruler context menu listener from the current editor.
155: */
156: private void removePopupMenu() {
157: if (!(fEditor instanceof ITextEditorExtension))
158: return;
159: ((ITextEditorExtension) fEditor)
160: .removeRulerContextMenuListener(fListener);
161: }
162:
163: /**
164: * Installs a submenu with <code>fEditor</code>'s ruler context menu that contains the choices
165: * for the quick diff reference. This allows the toggle action to lazily install the menu once
166: * quick diff has been enabled.
167: */
168: private void setPopupMenu() {
169: if (!(fEditor instanceof ITextEditorExtension))
170: return;
171: ((ITextEditorExtension) fEditor)
172: .addRulerContextMenuListener(fListener);
173: }
174:
175: /**
176: * States whether this toggle action has been installed and a incremental differ has been
177: * installed with the line number bar.
178: *
179: * @return <code>true</code> if a differ has been installed on <code>fEditor</code>.
180: */
181: boolean isConnected() {
182: if (!(fEditor instanceof ITextEditorExtension3))
183: return false;
184: return ((ITextEditorExtension3) fEditor)
185: .isChangeInformationShowing();
186: }
187:
188: /*
189: * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
190: */
191: public void run(IAction action) {
192: fProxy = action;
193: if (fEditor == null)
194: return;
195:
196: if (fEditor instanceof ITextEditorExtension3) {
197: ITextEditorExtension3 extension = (ITextEditorExtension3) fEditor;
198: extension.showChangeInformation(!extension
199: .isChangeInformationShowing());
200: }
201: }
202:
203: /*
204: * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection)
205: */
206: public void selectionChanged(IAction action, ISelection selection) {
207: fProxy = action;
208: }
209:
210: /*
211: * @see org.eclipse.ui.texteditor.IUpdate#update()
212: */
213: public void update() {
214: if (fProxy == null)
215: return;
216: if (isConnected())
217: fProxy.setText(QuickDiffMessages.quickdiff_toggle_disable);
218: else
219: fProxy.setText(QuickDiffMessages.quickdiff_toggle_enable);
220: }
221:
222: }
|