1 /*******************************************************************************
2  * Copyright (c) 2000, 2011 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.jdt.internal.ui.javaeditor;
15 
16 
17 import java.util.ArrayList;
18 import java.util.Collection;
19 import java.util.List;
20 
21 import org.eclipse.jface.action.IAction;
22 import org.eclipse.jface.action.IMenuListener;
23 import org.eclipse.jface.action.IMenuManager;
24 import org.eclipse.jface.action.MenuManager;
25 import org.eclipse.jface.action.Separator;
26 
27 import org.eclipse.ui.IActionBars;
28 import org.eclipse.ui.IEditorPart;
29 import org.eclipse.ui.IWorkbenchActionConstants;
30 import org.eclipse.ui.IWorkbenchPage;
31 import org.eclipse.ui.actions.RetargetAction;
32 import org.eclipse.ui.ide.IDEActionFactory;
33 
34 import org.eclipse.ui.texteditor.ITextEditor;
35 import org.eclipse.ui.texteditor.ITextEditorActionConstants;
36 import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
37 import org.eclipse.ui.texteditor.RetargetTextEditorAction;
38 
39 import org.eclipse.jdt.ui.actions.JdtActionConstants;
40 
41 import org.eclipse.jdt.internal.ui.JavaPluginImages;
42 import org.eclipse.jdt.internal.ui.text.java.CompletionProposalCategory;
43 import org.eclipse.jdt.internal.ui.text.java.CompletionProposalComputerRegistry;
44 
45 
46 public class BasicCompilationUnitEditorActionContributor extends BasicJavaEditorActionContributor {
47 
48 	/**
49 	 * A menu listener that can remove itself from the menu it listens to.
50 	 * @since 3.2
51 	 */
52     private final class MenuListener implements IMenuListener {
53         private final IMenuManager fMenu;
54 
MenuListener(IMenuManager menu)55 		public MenuListener(IMenuManager menu) {
56 			fMenu= menu;
57         }
58 
59 		@Override
menuAboutToShow(IMenuManager manager)60 		public void menuAboutToShow(IMenuManager manager) {
61 			for (SpecificContentAssistAction fSpecificAssistAction : fSpecificAssistActions) {
62 				fSpecificAssistAction.update();
63 			}
64 	    }
65 
dispose()66 		public void dispose() {
67 			fMenu.removeMenuListener(this);
68 		}
69     }
70 
71 	protected RetargetAction fRetargetContentAssist;
72 	protected RetargetTextEditorAction fContentAssist;
73 	protected RetargetTextEditorAction fContextInformation;
74 	protected RetargetTextEditorAction fQuickAssistAction;
75 	protected RetargetTextEditorAction fChangeEncodingAction;
76 
77 	/* @since 3.2 */
78 	protected SpecificContentAssistAction[] fSpecificAssistActions;
79 	/* @since 3.2 */
80 	private MenuListener fContentAssistMenuListener;
81 
82 
BasicCompilationUnitEditorActionContributor()83 	public BasicCompilationUnitEditorActionContributor() {
84 
85 		fRetargetContentAssist= new RetargetAction(JdtActionConstants.CONTENT_ASSIST,  JavaEditorMessages.ContentAssistProposal_label);
86 		fRetargetContentAssist.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
87 		fRetargetContentAssist.setImageDescriptor(JavaPluginImages.DESC_ELCL_CODE_ASSIST);
88 		fRetargetContentAssist.setDisabledImageDescriptor(JavaPluginImages.DESC_DLCL_CODE_ASSIST);
89 		markAsPartListener(fRetargetContentAssist);
90 
91 		fContentAssist= new RetargetTextEditorAction(JavaEditorMessages.getBundleForConstructedKeys(), "ContentAssistProposal."); //$NON-NLS-1$
92 		fContentAssist.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
93 		fContentAssist.setImageDescriptor(JavaPluginImages.DESC_ELCL_CODE_ASSIST);
94 		fContentAssist.setDisabledImageDescriptor(JavaPluginImages.DESC_DLCL_CODE_ASSIST);
95 
96 		fContextInformation= new RetargetTextEditorAction(JavaEditorMessages.getBundleForConstructedKeys(), "ContentAssistContextInformation."); //$NON-NLS-1$
97 		fContextInformation.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_CONTEXT_INFORMATION);
98 
99 		fQuickAssistAction= new RetargetTextEditorAction(JavaEditorMessages.getBundleForConstructedKeys(), "CorrectionAssistProposal."); //$NON-NLS-1$
100 		fQuickAssistAction.setActionDefinitionId(ITextEditorActionDefinitionIds.QUICK_ASSIST);
101 
102 		fChangeEncodingAction= new RetargetTextEditorAction(JavaEditorMessages.getBundleForConstructedKeys(), "Editor.ChangeEncodingAction."); //$NON-NLS-1$
103 	}
104 
105 	/*
106 	 * @see EditorActionBarContributor#contributeToMenu(IMenuManager)
107 	 */
108 	@Override
contributeToMenu(IMenuManager menu)109 	public void contributeToMenu(IMenuManager menu) {
110 
111 		super.contributeToMenu(menu);
112 		if (fContentAssistMenuListener != null)
113 			fContentAssistMenuListener.dispose();
114 
115 		IMenuManager editMenu= menu.findMenuUsingPath(IWorkbenchActionConstants.M_EDIT);
116 		if (editMenu != null) {
117 			editMenu.add(fChangeEncodingAction);
118 			IMenuManager caMenu= new MenuManager(JavaEditorMessages.BasicEditorActionContributor_specific_content_assist_menu, "specific_content_assist"); //$NON-NLS-1$
119 			editMenu.insertAfter(ITextEditorActionConstants.GROUP_ASSIST, caMenu);
120 
121 			caMenu.add(fRetargetContentAssist);
122 			Collection<CompletionProposalCategory> descriptors= CompletionProposalComputerRegistry.getDefault().getProposalCategories();
123 			List<IAction> specificAssistActions= new ArrayList<>(descriptors.size());
124 			for (CompletionProposalCategory cat : descriptors) {
125 				if (cat.hasComputers()) {
126 					IAction caAction= new SpecificContentAssistAction(cat);
127 					caMenu.add(caAction);
128 					specificAssistActions.add(caAction);
129 				}
130 			}
131 			fSpecificAssistActions= specificAssistActions.toArray(new SpecificContentAssistAction[specificAssistActions.size()]);
132 			if (fSpecificAssistActions.length > 0) {
133 				fContentAssistMenuListener= new MenuListener(caMenu);
134 				caMenu.addMenuListener(fContentAssistMenuListener);
135 			}
136 			caMenu.add(new Separator("context_info")); //$NON-NLS-1$
137 			caMenu.add(fContextInformation);
138 
139 			editMenu.appendToGroup(ITextEditorActionConstants.GROUP_ASSIST, fQuickAssistAction);
140 		}
141 	}
142 
143 	/*
144 	 * @see IEditorActionBarContributor#setActiveEditor(IEditorPart)
145 	 */
146 	@Override
setActiveEditor(IEditorPart part)147 	public void setActiveEditor(IEditorPart part) {
148 		super.setActiveEditor(part);
149 
150 		ITextEditor textEditor= null;
151 		if (part instanceof ITextEditor)
152 			textEditor= (ITextEditor) part;
153 
154 		fContentAssist.setAction(getAction(textEditor, ITextEditorActionConstants.CONTENT_ASSIST));
155 		fContextInformation.setAction(getAction(textEditor, ITextEditorActionConstants.CONTENT_ASSIST_CONTEXT_INFORMATION));
156 		fQuickAssistAction.setAction(getAction(textEditor, ITextEditorActionConstants.QUICK_ASSIST));
157 
158 		if (fSpecificAssistActions != null) {
159 			for (SpecificContentAssistAction assistAction : fSpecificAssistActions) {
160 				assistAction.setActiveEditor(part);
161 			}
162 		}
163 
164 		fChangeEncodingAction.setAction(getAction(textEditor, ITextEditorActionConstants.CHANGE_ENCODING));
165 
166 		IActionBars actionBars= getActionBars();
167 		actionBars.setGlobalActionHandler(JdtActionConstants.SHIFT_RIGHT, getAction(textEditor, "ShiftRight")); //$NON-NLS-1$
168 		actionBars.setGlobalActionHandler(JdtActionConstants.SHIFT_LEFT, getAction(textEditor, "ShiftLeft")); //$NON-NLS-1$
169 
170 		actionBars.setGlobalActionHandler(IDEActionFactory.ADD_TASK.getId(), getAction(textEditor, IDEActionFactory.ADD_TASK.getId()));
171 		actionBars.setGlobalActionHandler(IDEActionFactory.BOOKMARK.getId(), getAction(textEditor, IDEActionFactory.BOOKMARK.getId()));
172 
173 		actionBars.setGlobalActionHandler(IDEActionFactory.OPEN_PROJECT.getId(), getAction(textEditor, IDEActionFactory.OPEN_PROJECT.getId()));
174 		actionBars.setGlobalActionHandler(IDEActionFactory.CLOSE_PROJECT.getId(), getAction(textEditor, IDEActionFactory.CLOSE_PROJECT.getId()));
175 		actionBars.setGlobalActionHandler(IDEActionFactory.CLOSE_UNRELATED_PROJECTS.getId(), getAction(textEditor, IDEActionFactory.CLOSE_UNRELATED_PROJECTS.getId()));
176 	}
177 
178 	/*
179 	 * @see IEditorActionBarContributor#init(IActionBars, IWorkbenchPage)
180 	 */
181 	@Override
init(IActionBars bars, IWorkbenchPage page)182 	public void init(IActionBars bars, IWorkbenchPage page) {
183 		super.init(bars, page);
184 		// register actions that have a dynamic editor.
185 		bars.setGlobalActionHandler(JdtActionConstants.CONTENT_ASSIST, fContentAssist);
186 	}
187 
188 	/*
189 	 * @see org.eclipse.jdt.internal.ui.javaeditor.BasicJavaEditorActionContributor#dispose()
190 	 * @since 3.1
191 	 */
192 	@Override
dispose()193 	public void dispose() {
194 		if (fRetargetContentAssist != null) {
195 			fRetargetContentAssist.dispose();
196 			fRetargetContentAssist= null;
197 		}
198 		if (fContentAssistMenuListener != null) {
199 			fContentAssistMenuListener.dispose();
200 			fContentAssistMenuListener= null;
201 		}
202 		super.dispose();
203 	}
204 }
205