1 /*******************************************************************************
2 * Copyright (c) 2000, 2011 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
9 * IBM Corporation - initial API and implementation
10 * Eric Rizzo - replaced Collapse All action with generic equivalent
11 *******************************************************************************/
13 package org.eclipse.jdt.internal.ui.packageview;
15 import org.eclipse.swt.SWT;
16 import org.eclipse.swt.events.KeyEvent;
18 import org.eclipse.core.resources.IContainer;
19 import org.eclipse.core.resources.IProject;
20 import org.eclipse.core.resources.ResourcesPlugin;
22 import org.eclipse.jface.action.GroupMarker;
23 import org.eclipse.jface.action.IAction;
24 import org.eclipse.jface.action.IMenuManager;
25 import org.eclipse.jface.action.IToolBarManager;
26 import org.eclipse.jface.action.Separator;
27 import org.eclipse.jface.commands.ActionHandler;
28 import org.eclipse.jface.util.IPropertyChangeListener;
29 import org.eclipse.jface.util.OpenStrategy;
30 import org.eclipse.jface.util.PropertyChangeEvent;
31 import org.eclipse.jface.viewers.DoubleClickEvent;
32 import org.eclipse.jface.viewers.ISelection;
33 import org.eclipse.jface.viewers.ISelectionChangedListener;
34 import org.eclipse.jface.viewers.IStructuredSelection;
35 import org.eclipse.jface.viewers.ITreeSelection;
36 import org.eclipse.jface.viewers.SelectionChangedEvent;
37 import org.eclipse.jface.viewers.TreePath;
38 import org.eclipse.jface.viewers.TreeViewer;
40 import org.eclipse.ui.IActionBars;
41 import org.eclipse.ui.IMemento;
42 import org.eclipse.ui.IWorkbenchActionConstants;
43 import org.eclipse.ui.IWorkbenchCommandConstants;
44 import org.eclipse.ui.IWorkbenchPartSite;
45 import org.eclipse.ui.IWorkingSet;
46 import org.eclipse.ui.IWorkingSetManager;
47 import org.eclipse.ui.actions.ActionFactory;
48 import org.eclipse.ui.actions.ActionGroup;
49 import org.eclipse.ui.actions.OpenInNewWindowAction;
50 import org.eclipse.ui.handlers.CollapseAllHandler;
51 import org.eclipse.ui.handlers.IHandlerService;
52 import org.eclipse.ui.views.framelist.BackAction;
53 import org.eclipse.ui.views.framelist.ForwardAction;
54 import org.eclipse.ui.views.framelist.Frame;
55 import org.eclipse.ui.views.framelist.FrameAction;
56 import org.eclipse.ui.views.framelist.FrameList;
57 import org.eclipse.ui.views.framelist.GoIntoAction;
58 import org.eclipse.ui.views.framelist.TreeFrame;
59 import org.eclipse.ui.views.framelist.UpAction;
61 import org.eclipse.jdt.core.IClassFile;
62 import org.eclipse.jdt.core.ICompilationUnit;
63 import org.eclipse.jdt.core.IJavaElement;
64 import org.eclipse.jdt.core.IOpenable;
65 import org.eclipse.jdt.core.JavaCore;
67 import org.eclipse.jdt.ui.IContextMenuConstants;
68 import org.eclipse.jdt.ui.PreferenceConstants;
69 import org.eclipse.jdt.ui.actions.BuildActionGroup;
70 import org.eclipse.jdt.ui.actions.CCPActionGroup;
71 import org.eclipse.jdt.ui.actions.CustomFiltersActionGroup;
72 import org.eclipse.jdt.ui.actions.GenerateActionGroup;
73 import org.eclipse.jdt.ui.actions.ImportActionGroup;
74 import org.eclipse.jdt.ui.actions.JavaSearchActionGroup;
75 import org.eclipse.jdt.ui.actions.JdtActionConstants;
76 import org.eclipse.jdt.ui.actions.NavigateActionGroup;
77 import org.eclipse.jdt.ui.actions.OpenProjectAction;
78 import org.eclipse.jdt.ui.actions.ProjectActionGroup;
79 import org.eclipse.jdt.ui.actions.RefactorActionGroup;
81 import org.eclipse.jdt.internal.ui.actions.CollapseAllAction;
82 import org.eclipse.jdt.internal.ui.actions.CompositeActionGroup;
83 import org.eclipse.jdt.internal.ui.actions.NewWizardsActionGroup;
84 import org.eclipse.jdt.internal.ui.actions.SelectAllAction;
85 import org.eclipse.jdt.internal.ui.viewsupport.BasicElementLabels;
86 import org.eclipse.jdt.internal.ui.wizards.buildpaths.newsourcepage.GenerateBuildPathActionGroup;
87 import org.eclipse.jdt.internal.ui.workingsets.ViewActionGroup;
89 class PackageExplorerActionGroup extends CompositeActionGroup {
91 private static final String FRAME_ACTION_SEPARATOR_ID= "FRAME_ACTION_SEPARATOR_ID"; //$NON-NLS-1$
92 private static final String FRAME_ACTION_GROUP_ID= "FRAME_ACTION_GROUP_ID"; //$NON-NLS-1$
94 private PackageExplorerPart fPart;
96 private FrameList fFrameList;
97 private GoIntoAction fZoomInAction;
98 private BackAction fBackAction;
99 private ForwardAction fForwardAction;
100 private UpAction fUpAction;
101 private boolean fFrameActionsShown;
104 private GotoTypeAction fGotoTypeAction;
105 private GotoPackageAction fGotoPackageAction;
106 private GotoResourceAction fGotoResourceAction;
107 private CollapseAllAction fCollapseAllAction;
108 private SelectAllAction fSelectAllAction;
111 private ToggleLinkingAction fToggleLinkingAction;
113 private RefactorActionGroup fRefactorActionGroup;
114 private NavigateActionGroup fNavigateActionGroup;
115 private ViewActionGroup fViewActionGroup;
117 private CustomFiltersActionGroup fCustomFiltersActionGroup;
119 private IAction fGotoRequiredProjectAction;
121 private ProjectActionGroup fProjectActionGroup;
123 public PackageExplorerActionGroup(PackageExplorerPart part) {
126 fFrameActionsShown= false;
127 TreeViewer viewer= part.getTreeViewer();
129 IPropertyChangeListener workingSetListener= new IPropertyChangeListener() {
130 public void propertyChange(PropertyChangeEvent event) {
131 doWorkingSetChanged(event);
135 IWorkbenchPartSite site = fPart.getSite();
136 setGroups(new ActionGroup[] {
137 new NewWizardsActionGroup(site),
138 fNavigateActionGroup= new NavigateActionGroup(fPart),
139 new CCPActionGroup(fPart),
140 new GenerateBuildPathActionGroup(fPart),
141 new GenerateActionGroup(fPart),
142 fRefactorActionGroup= new RefactorActionGroup(fPart),
143 new ImportActionGroup(fPart),
144 new BuildActionGroup(fPart),
145 new JavaSearchActionGroup(fPart),
146 fProjectActionGroup= new ProjectActionGroup(fPart),
147 fViewActionGroup= new ViewActionGroup(fPart.getRootMode(), workingSetListener, site),
148 fCustomFiltersActionGroup= new CustomFiltersActionGroup(fPart, viewer),
149 new LayoutActionGroup(fPart)
153 fViewActionGroup.fillFilters(viewer);
155 PackagesFrameSource frameSource= new PackagesFrameSource(fPart);
156 fFrameList= new FrameList(frameSource);
157 frameSource.connectTo(fFrameList);
158 fZoomInAction= new GoIntoAction(fFrameList);
159 fPart.getSite().getSelectionProvider().addSelectionChangedListener(new ISelectionChangedListener() {
160 public void selectionChanged(SelectionChangedEvent event) {
161 fZoomInAction.update();
165 fBackAction= new BackAction(fFrameList);
166 fForwardAction= new ForwardAction(fFrameList);
167 fUpAction= new UpAction(fFrameList);
168 fFrameList.addPropertyChangeListener(new IPropertyChangeListener() { // connect after the actions (order of property listener)
169 public void propertyChange(PropertyChangeEvent event) {
171 fPart.updateToolbar();
175 fGotoTypeAction= new GotoTypeAction(fPart);
176 fGotoPackageAction= new GotoPackageAction(fPart);
177 fGotoResourceAction= new GotoResourceAction(fPart);
179 fCollapseAllAction= new CollapseAllAction(fPart.getTreeViewer());
180 fCollapseAllAction.setActionDefinitionId(CollapseAllHandler.COMMAND_ID);
181 fToggleLinkingAction = new ToggleLinkingAction(fPart);
182 fToggleLinkingAction.setActionDefinitionId(IWorkbenchCommandConstants.NAVIGATE_TOGGLE_LINK_WITH_EDITOR);
184 fGotoRequiredProjectAction= new GotoRequiredProjectAction(fPart);
185 fSelectAllAction= new SelectAllAction(fPart.getTreeViewer());
189 public void dispose() {
194 //---- Persistent state -----------------------------------------------------------------------
196 /* package */ void restoreFilterAndSorterState(IMemento memento) {
197 fViewActionGroup.restoreState(memento);
198 fCustomFiltersActionGroup.restoreState(memento);
201 /* package */ void saveFilterAndSorterState(IMemento memento) {
202 fViewActionGroup.saveState(memento);
203 fCustomFiltersActionGroup.saveState(memento);
206 //---- Action Bars ----------------------------------------------------------------------------
209 public void fillActionBars(IActionBars actionBars) {
210 super.fillActionBars(actionBars);
211 setGlobalActionHandlers(actionBars);
212 fillToolBar(actionBars.getToolBarManager());
213 fillViewMenu(actionBars.getMenuManager());
216 private void setGlobalActionHandlers(IActionBars actionBars) {
217 // Navigate Go Into and Go To actions.
218 actionBars.setGlobalActionHandler(IWorkbenchActionConstants.GO_INTO, fZoomInAction);
219 actionBars.setGlobalActionHandler(ActionFactory.BACK.getId(), fBackAction);
220 actionBars.setGlobalActionHandler(ActionFactory.FORWARD.getId(), fForwardAction);
221 actionBars.setGlobalActionHandler(IWorkbenchActionConstants.UP, fUpAction);
222 actionBars.setGlobalActionHandler(IWorkbenchActionConstants.GO_TO_RESOURCE, fGotoResourceAction);
223 actionBars.setGlobalActionHandler(JdtActionConstants.GOTO_TYPE, fGotoTypeAction);
224 actionBars.setGlobalActionHandler(JdtActionConstants.GOTO_PACKAGE, fGotoPackageAction);
225 actionBars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(), fSelectAllAction);
227 fRefactorActionGroup.retargetFileMenuActions(actionBars);
229 IHandlerService handlerService= (IHandlerService) fPart.getViewSite().getService(IHandlerService.class);
230 handlerService.activateHandler(IWorkbenchCommandConstants.NAVIGATE_TOGGLE_LINK_WITH_EDITOR, new ActionHandler(fToggleLinkingAction));
231 handlerService.activateHandler(CollapseAllHandler.COMMAND_ID, new ActionHandler(fCollapseAllAction));
234 /* package */ void fillToolBar(IToolBarManager toolBar) {
235 if (fBackAction.isEnabled() || fUpAction.isEnabled() || fForwardAction.isEnabled()) {
236 toolBar.add(fBackAction);
237 toolBar.add(fForwardAction);
238 toolBar.add(fUpAction);
239 toolBar.add(new Separator(FRAME_ACTION_SEPARATOR_ID));
240 fFrameActionsShown= true;
242 toolBar.add(new GroupMarker(FRAME_ACTION_GROUP_ID));
243 toolBar.add(fCollapseAllAction);
244 toolBar.add(fToggleLinkingAction);
245 toolBar.update(true);
248 public void updateToolBar(IToolBarManager toolBar) {
250 boolean hasBeenFrameActionsShown= fFrameActionsShown;
251 fFrameActionsShown= fBackAction.isEnabled() || fUpAction.isEnabled() || fForwardAction.isEnabled();
252 if (fFrameActionsShown != hasBeenFrameActionsShown) {
253 if (hasBeenFrameActionsShown) {
254 toolBar.remove(fBackAction.getId());
255 toolBar.remove(fForwardAction.getId());
256 toolBar.remove(fUpAction.getId());
257 toolBar.remove(FRAME_ACTION_SEPARATOR_ID);
259 toolBar.prependToGroup(FRAME_ACTION_GROUP_ID, new Separator(FRAME_ACTION_SEPARATOR_ID));
260 toolBar.prependToGroup(FRAME_ACTION_GROUP_ID, fUpAction);
261 toolBar.prependToGroup(FRAME_ACTION_GROUP_ID, fForwardAction);
262 toolBar.prependToGroup(FRAME_ACTION_GROUP_ID, fBackAction);
264 toolBar.update(true);
268 /* package */ void fillViewMenu(IMenuManager menu) {
269 menu.add(new Separator());
270 menu.add(fToggleLinkingAction);
271 menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
272 menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS+"-end"));//$NON-NLS-1$
275 //---- Context menu -------------------------------------------------------------------------
278 public void fillContextMenu(IMenuManager menu) {
279 IStructuredSelection selection= (IStructuredSelection)getContext().getSelection();
280 int size= selection.size();
281 Object element= selection.getFirstElement();
283 if (element instanceof ClassPathContainer.RequiredProjectWrapper)
284 menu.appendToGroup(IContextMenuConstants.GROUP_SHOW, fGotoRequiredProjectAction);
286 addGotoMenu(menu, element, size);
288 addOpenNewWindowAction(menu, element);
290 super.fillContextMenu(menu);
293 private void addGotoMenu(IMenuManager menu, Object element, int size) {
294 boolean enabled= size == 1 && fPart.getTreeViewer().isExpandable(element) && (isGoIntoTarget(element) || element instanceof IContainer);
295 fZoomInAction.setEnabled(enabled);
297 menu.appendToGroup(IContextMenuConstants.GROUP_GOTO, fZoomInAction);
300 private boolean isGoIntoTarget(Object element) {
303 if (element instanceof IJavaElement) {
304 int type= ((IJavaElement)element).getElementType();
305 return type == IJavaElement.JAVA_PROJECT ||
306 type == IJavaElement.PACKAGE_FRAGMENT_ROOT ||
307 type == IJavaElement.PACKAGE_FRAGMENT;
309 if (element instanceof IWorkingSet) {
315 private void addOpenNewWindowAction(IMenuManager menu, Object element) {
316 if (element instanceof IJavaElement) {
317 element= ((IJavaElement)element).getResource();
320 // fix for 64890 Package explorer out of sync when open/closing projects [package explorer] 64890
321 if (element instanceof IProject && !((IProject)element).isOpen())
324 if (!(element instanceof IContainer))
327 IContextMenuConstants.GROUP_OPEN,
328 new OpenInNewWindowAction(fPart.getSite().getWorkbenchWindow(), (IContainer)element));
331 //---- Key board and mouse handling ------------------------------------------------------------
333 /* package*/ void handleDoubleClick(DoubleClickEvent event) {
334 TreeViewer viewer= fPart.getTreeViewer();
335 IStructuredSelection selection= (IStructuredSelection)event.getSelection();
336 Object element= selection.getFirstElement();
337 if (viewer.isExpandable(element)) {
338 if (doubleClickGoesInto()) {
339 // don't zoom into compilation units and class files
340 if (element instanceof ICompilationUnit || element instanceof IClassFile)
342 if (element instanceof IOpenable || element instanceof IContainer || element instanceof IWorkingSet) {
346 IAction openAction= fNavigateActionGroup.getOpenAction();
347 if (openAction != null && openAction.isEnabled() && OpenStrategy.getOpenMethod() == OpenStrategy.DOUBLE_CLICK)
349 if (selection instanceof ITreeSelection) {
350 TreePath[] paths= ((ITreeSelection)selection).getPathsFor(element);
351 for (int i= 0; i < paths.length; i++) {
352 viewer.setExpandedState(paths[i], !viewer.getExpandedState(paths[i]));
355 viewer.setExpandedState(element, !viewer.getExpandedState(element));
358 } else if (element instanceof IProject && !((IProject) element).isOpen()) {
359 OpenProjectAction openProjectAction= fProjectActionGroup.getOpenProjectAction();
360 if (openProjectAction.isEnabled()) {
361 openProjectAction.run();
367 * Called by Package Explorer.
369 * @param event the open event
370 * @param activate <code>true</code> if the opened editor should be activated
372 /* package */void handleOpen(ISelection event, boolean activate) {
373 IAction openAction= fNavigateActionGroup.getOpenAction();
374 if (openAction != null && openAction.isEnabled()) {
375 // XXX: should use the given arguments instead of using org.eclipse.jface.util.OpenStrategy.activateOnOpen()
381 /* package */ void handleKeyEvent(KeyEvent event) {
382 if (event.stateMask != 0)
385 if (event.keyCode == SWT.BS) {
386 if (fUpAction != null && fUpAction.isEnabled()) {
393 private void doWorkingSetChanged(PropertyChangeEvent event) {
394 if (ViewActionGroup.MODE_CHANGED.equals(event.getProperty())) {
395 fPart.rootModeChanged(((Integer)event.getNewValue()).intValue());
396 Object oldInput= null;
397 Object newInput= null;
398 if (fPart.getRootMode() == PackageExplorerPart.PROJECTS_AS_ROOTS) {
399 oldInput= fPart.getWorkingSetModel();
400 newInput= JavaCore.create(ResourcesPlugin.getWorkspace().getRoot());
402 oldInput= JavaCore.create(ResourcesPlugin.getWorkspace().getRoot());
403 newInput= fPart.getWorkingSetModel();
405 if (oldInput != null && newInput != null) {
407 for (int i= 0; (frame= fFrameList.getFrame(i)) != null; i++) {
408 if (frame instanceof TreeFrame) {
409 TreeFrame treeFrame= (TreeFrame)frame;
410 if (oldInput.equals(treeFrame.getInput()))
411 treeFrame.setInput(newInput);
416 IWorkingSet workingSet= (IWorkingSet) event.getNewValue();
418 String workingSetLabel= null;
419 if (workingSet != null)
420 workingSetLabel= BasicElementLabels.getWorkingSetLabel(workingSet);
421 fPart.setWorkingSetLabel(workingSetLabel);
424 String property= event.getProperty();
425 if (IWorkingSetManager.CHANGE_WORKING_SET_CONTENT_CHANGE.equals(property)) {
426 TreeViewer viewer= fPart.getTreeViewer();
427 viewer.getControl().setRedraw(false);
429 viewer.getControl().setRedraw(true);
434 private boolean doubleClickGoesInto() {
435 return PreferenceConstants.DOUBLE_CLICK_GOES_INTO.equals(PreferenceConstants.getPreferenceStore().getString(PreferenceConstants.DOUBLE_CLICK));
438 public FrameAction getUpAction() {
442 public FrameAction getBackAction() {
445 public FrameAction getForwardAction() {
446 return fForwardAction;
449 public ViewActionGroup getWorkingSetActionGroup() {
450 return fViewActionGroup;
453 public CustomFiltersActionGroup getCustomFilterActionGroup() {
454 return fCustomFiltersActionGroup;
457 public FrameList getFrameList() {