]> git.uio.no Git - ifi-stolz-refaktor.git/blame - case-study/jdt-before/ui/org/eclipse/jdt/internal/ui/typehierarchy/TypeHierarchyViewPart.java
Case Study: adding data and statistics
[ifi-stolz-refaktor.git] / case-study / jdt-before / ui / org / eclipse / jdt / internal / ui / typehierarchy / TypeHierarchyViewPart.java
CommitLineData
1b2798f6
EK
1/*******************************************************************************
2 * Copyright (c) 2000, 2012 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
7 *
8 * Contributors:
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11package org.eclipse.jdt.internal.ui.typehierarchy;
12
13import java.lang.reflect.InvocationTargetException;
14import java.util.ArrayList;
15import java.util.Arrays;
16import java.util.Iterator;
17import java.util.List;
18
19import org.eclipse.help.IContextProvider;
20
21import org.eclipse.swt.SWT;
22import org.eclipse.swt.custom.BusyIndicator;
23import org.eclipse.swt.custom.CLabel;
24import org.eclipse.swt.custom.SashForm;
25import org.eclipse.swt.custom.ViewForm;
26import org.eclipse.swt.dnd.DND;
27import org.eclipse.swt.dnd.DropTarget;
28import org.eclipse.swt.dnd.DropTargetAdapter;
29import org.eclipse.swt.dnd.FileTransfer;
30import org.eclipse.swt.dnd.Transfer;
31import org.eclipse.swt.events.ControlEvent;
32import org.eclipse.swt.events.ControlListener;
33import org.eclipse.swt.events.FocusEvent;
34import org.eclipse.swt.events.FocusListener;
35import org.eclipse.swt.events.KeyAdapter;
36import org.eclipse.swt.events.KeyEvent;
37import org.eclipse.swt.events.KeyListener;
38import org.eclipse.swt.graphics.Point;
39import org.eclipse.swt.widgets.Composite;
40import org.eclipse.swt.widgets.Control;
41import org.eclipse.swt.widgets.Display;
42import org.eclipse.swt.widgets.Label;
43import org.eclipse.swt.widgets.ScrollBar;
44import org.eclipse.swt.widgets.ToolBar;
45
46import org.eclipse.core.runtime.Assert;
47import org.eclipse.core.runtime.IProgressMonitor;
48import org.eclipse.core.runtime.IStatus;
49import org.eclipse.core.runtime.OperationCanceledException;
50import org.eclipse.core.runtime.Status;
51import org.eclipse.core.runtime.jobs.Job;
52
53import org.eclipse.jface.action.IMenuListener;
54import org.eclipse.jface.action.IMenuManager;
55import org.eclipse.jface.action.IStatusLineManager;
56import org.eclipse.jface.action.IToolBarManager;
57import org.eclipse.jface.action.MenuManager;
58import org.eclipse.jface.action.Separator;
59import org.eclipse.jface.action.ToolBarManager;
60import org.eclipse.jface.commands.ActionHandler;
61import org.eclipse.jface.dialogs.IDialogSettings;
62import org.eclipse.jface.dialogs.MessageDialog;
63import org.eclipse.jface.util.DelegatingDropAdapter;
64import org.eclipse.jface.util.IPropertyChangeListener;
65import org.eclipse.jface.util.PropertyChangeEvent;
66import org.eclipse.jface.viewers.AbstractTreeViewer;
67import org.eclipse.jface.viewers.IBasicPropertyConstants;
68import org.eclipse.jface.viewers.ISelection;
69import org.eclipse.jface.viewers.ISelectionChangedListener;
70import org.eclipse.jface.viewers.IStructuredSelection;
71import org.eclipse.jface.viewers.SelectionChangedEvent;
72import org.eclipse.jface.viewers.StructuredSelection;
73import org.eclipse.jface.viewers.StructuredViewer;
74
75import org.eclipse.ui.IActionBars;
76import org.eclipse.ui.IEditorPart;
77import org.eclipse.ui.IMemento;
78import org.eclipse.ui.IPartListener2;
79import org.eclipse.ui.IViewSite;
80import org.eclipse.ui.IWorkbenchActionConstants;
81import org.eclipse.ui.IWorkbenchCommandConstants;
82import org.eclipse.ui.IWorkbenchPart;
83import org.eclipse.ui.IWorkbenchPartReference;
84import org.eclipse.ui.IWorkbenchPartSite;
85import org.eclipse.ui.IWorkingSet;
86import org.eclipse.ui.IWorkingSetManager;
87import org.eclipse.ui.OpenAndLinkWithEditorHelper;
88import org.eclipse.ui.PartInitException;
89import org.eclipse.ui.PlatformUI;
90import org.eclipse.ui.actions.ActionContext;
91import org.eclipse.ui.actions.ActionFactory;
92import org.eclipse.ui.actions.ActionGroup;
93import org.eclipse.ui.handlers.IHandlerService;
94import org.eclipse.ui.part.IShowInSource;
95import org.eclipse.ui.part.IShowInTargetList;
96import org.eclipse.ui.part.PageBook;
97import org.eclipse.ui.part.PluginTransfer;
98import org.eclipse.ui.part.ResourceTransfer;
99import org.eclipse.ui.part.ShowInContext;
100import org.eclipse.ui.part.ViewPart;
101import org.eclipse.ui.views.navigator.LocalSelectionTransfer;
102
103import org.eclipse.jdt.core.IJavaElement;
104import org.eclipse.jdt.core.IMember;
105import org.eclipse.jdt.core.IType;
106import org.eclipse.jdt.core.ITypeHierarchy;
107import org.eclipse.jdt.core.ITypeRoot;
108import org.eclipse.jdt.core.JavaCore;
109import org.eclipse.jdt.core.JavaModelException;
110
111import org.eclipse.jdt.internal.corext.util.Messages;
112
113import org.eclipse.jdt.ui.IContextMenuConstants;
114import org.eclipse.jdt.ui.ITypeHierarchyViewPart;
115import org.eclipse.jdt.ui.JavaUI;
116import org.eclipse.jdt.ui.PreferenceConstants;
117import org.eclipse.jdt.ui.actions.CCPActionGroup;
118import org.eclipse.jdt.ui.actions.GenerateActionGroup;
119import org.eclipse.jdt.ui.actions.JavaSearchActionGroup;
120import org.eclipse.jdt.ui.actions.OpenAction;
121import org.eclipse.jdt.ui.actions.OpenEditorActionGroup;
122import org.eclipse.jdt.ui.actions.OpenViewActionGroup;
123import org.eclipse.jdt.ui.actions.RefactorActionGroup;
124
125import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
126import org.eclipse.jdt.internal.ui.JavaPlugin;
127import org.eclipse.jdt.internal.ui.actions.CompositeActionGroup;
128import org.eclipse.jdt.internal.ui.actions.NewWizardsActionGroup;
129import org.eclipse.jdt.internal.ui.actions.SelectAllAction;
130import org.eclipse.jdt.internal.ui.dnd.EditorInputTransferDragAdapter;
131import org.eclipse.jdt.internal.ui.dnd.JdtViewerDragAdapter;
132import org.eclipse.jdt.internal.ui.dnd.ResourceTransferDragAdapter;
133import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility;
134import org.eclipse.jdt.internal.ui.packageview.FileTransferDragAdapter;
135import org.eclipse.jdt.internal.ui.packageview.PluginTransferDropAdapter;
136import org.eclipse.jdt.internal.ui.packageview.SelectionTransferDragAdapter;
137import org.eclipse.jdt.internal.ui.preferences.MembersOrderPreferenceCache;
138import org.eclipse.jdt.internal.ui.util.ExceptionHandler;
139import org.eclipse.jdt.internal.ui.util.JavaUIHelp;
140import org.eclipse.jdt.internal.ui.util.SelectionUtil;
141import org.eclipse.jdt.internal.ui.viewsupport.IViewPartInputProvider;
142import org.eclipse.jdt.internal.ui.viewsupport.JavaUILabelProvider;
143import org.eclipse.jdt.internal.ui.viewsupport.SelectionProviderMediator;
144import org.eclipse.jdt.internal.ui.viewsupport.StatusBarUpdater;
145import org.eclipse.jdt.internal.ui.workingsets.WorkingSetFilterActionGroup;
146
147
148/**
149 * View showing the super types/sub types of its input.
150 */
151public class TypeHierarchyViewPart extends ViewPart implements ITypeHierarchyViewPart, IViewPartInputProvider {
152
153 private static final String DIALOGSTORE_HIERARCHYVIEW= "TypeHierarchyViewPart.hierarchyview"; //$NON-NLS-1$
154 private static final String DIALOGSTORE_VIEWLAYOUT= "TypeHierarchyViewPart.orientation"; //$NON-NLS-1$
155 private static final String DIALOGSTORE_QUALIFIED_NAMES= "TypeHierarchyViewPart.qualifiednames"; //$NON-NLS-1$
156 private static final String DIALOGSTORE_LINKEDITORS= "TypeHierarchyViewPart.linkeditors"; //$NON-NLS-1$
157
158 private static final String TAG_INPUT= "input"; //$NON-NLS-1$
159 private static final String TAG_VIEW= "view"; //$NON-NLS-1$
160 private static final String TAG_LAYOUT= "orientation"; //$NON-NLS-1$
161 private static final String TAG_RATIO= "ratio"; //$NON-NLS-1$
162 private static final String TAG_SELECTION= "selection"; //$NON-NLS-1$
163 private static final String TAG_VERTICAL_SCROLL= "vertical_scroll"; //$NON-NLS-1$
164 private static final String TAG_QUALIFIED_NAMES= "qualified_names"; //$NON-NLS-1$
165 private static final String TAG_EDITOR_LINKING= "link_editors"; //$NON-NLS-1$
166
167 private static final String GROUP_FOCUS= "group.focus"; //$NON-NLS-1$
168
169
170
171 // the selected type in the hierarchy view
172 private IType fSelectedType;
173 // input elements or null
174 private IJavaElement[] fInputElements;
175
176 // history of input elements. No duplicates
177 private ArrayList<IJavaElement[]> fInputHistory;
178
179 private IMemento fMemento;
180 private IDialogSettings fDialogSettings;
181
182 private TypeHierarchyLifeCycle fHierarchyLifeCycle;
183 private ITypeHierarchyLifeCycleListener fTypeHierarchyLifeCycleListener;
184
185 private IPropertyChangeListener fPropertyChangeListener;
186
187 private SelectionProviderMediator fSelectionProviderMediator;
188 private ISelectionChangedListener fSelectionChangedListener;
189 private IPartListener2 fPartListener;
190
191 private int fCurrentLayout;
192 private boolean fInComputeLayout;
193
194 private boolean fLinkingEnabled;
195 private boolean fShowQualifiedTypeNames;
196 private boolean fSelectInEditor;
197
198 private boolean fIsVisible;
199 private boolean fNeedRefresh;
200 private boolean fIsEnableMemberFilter;
201 private boolean fIsRefreshRunnablePosted;
202
203 private int fCurrentViewerIndex;
204 private TypeHierarchyViewer[] fAllViewers;
205
206 private MethodsViewer fMethodsViewer;
207
208 private SashForm fTypeMethodsSplitter;
209 private PageBook fViewerbook;
210 private PageBook fPagebook;
211
212 private Label fNoHierarchyShownLabel;
213 private Label fEmptyTypesViewer;
214
215 private ViewForm fTypeViewerViewForm;
216 private ViewForm fMethodViewerViewForm;
217
218 private CLabel fMethodViewerPaneLabel;
219 private JavaUILabelProvider fPaneLabelProvider;
220 private Composite fParent;
221
222 private ToggleViewAction[] fViewActions;
223 private ToggleLinkingAction fToggleLinkingAction;
224 private HistoryDropDownAction fHistoryDropDownAction;
225 private ToggleOrientationAction[] fToggleOrientationActions;
226 private EnableMemberFilterAction fEnableMemberFilterAction;
227 private ShowQualifiedTypeNamesAction fShowQualifiedTypeNamesAction;
228 private FocusOnTypeAction fFocusOnTypeAction;
229 private FocusOnSelectionAction fFocusOnSelectionAction;
230 private CompositeActionGroup fActionGroups;
231 private SelectAllAction fSelectAllAction;
232
233 private WorkingSetFilterActionGroup fWorkingSetActionGroup;
234 private Job fRestoreStateJob;
235
236 /**
237 * Helper to open and activate editors.
238 *
239 * @since 3.5
240 */
241 private OpenAndLinkWithEditorHelper fTypeOpenAndLinkWithEditorHelper;
242
243 private OpenAction fOpenAction;
244
245 /**
246 * Indicates whether the restore job was canceled explicitly.
247 *
248 * @since 3.6
249 */
250 private boolean fRestoreJobCanceledExplicitly= true;
251
252 /**
253 * Indicates whether empty viewers should keep showing. If false, replace them with
254 * fEmptyTypesViewer.
255 *
256 * @since 3.6
257 */
258 private boolean fKeepShowingEmptyViewers= true;
259
260
261 public TypeHierarchyViewPart() {
262 fSelectedType= null;
263 fInputElements= null;
264 fIsVisible= false;
265 fIsRefreshRunnablePosted= false;
266 fSelectInEditor= true;
267 fRestoreStateJob= null;
268
269 fHierarchyLifeCycle= new TypeHierarchyLifeCycle(this);
270 fTypeHierarchyLifeCycleListener= new ITypeHierarchyLifeCycleListener() {
271 public void typeHierarchyChanged(TypeHierarchyLifeCycle typeHierarchy, IType[] changedTypes) {
272 doTypeHierarchyChanged(typeHierarchy, changedTypes);
273 }
274 };
275 fHierarchyLifeCycle.addChangedListener(fTypeHierarchyLifeCycleListener);
276
277 fPropertyChangeListener= new IPropertyChangeListener() {
278 public void propertyChange(PropertyChangeEvent event) {
279 doPropertyChange(event);
280 }
281 };
282 PreferenceConstants.getPreferenceStore().addPropertyChangeListener(fPropertyChangeListener);
283
284 fIsEnableMemberFilter= false;
285
286 fInputHistory= new ArrayList<IJavaElement[]>();
287 fAllViewers= null;
288
289 fViewActions= new ToggleViewAction[] {
290 new ToggleViewAction(this, HIERARCHY_MODE_CLASSIC),
291 new ToggleViewAction(this, HIERARCHY_MODE_SUPERTYPES),
292 new ToggleViewAction(this, HIERARCHY_MODE_SUBTYPES)
293 };
294
295 fDialogSettings= JavaPlugin.getDefault().getDialogSettings();
296
297 fHistoryDropDownAction= new HistoryDropDownAction(this);
298 fHistoryDropDownAction.setEnabled(false);
299
300 fToggleOrientationActions= new ToggleOrientationAction[] {
301 new ToggleOrientationAction(this, VIEW_LAYOUT_VERTICAL),
302 new ToggleOrientationAction(this, VIEW_LAYOUT_HORIZONTAL),
303 new ToggleOrientationAction(this, VIEW_LAYOUT_AUTOMATIC),
304 new ToggleOrientationAction(this, VIEW_LAYOUT_SINGLE)
305 };
306
307 fEnableMemberFilterAction= new EnableMemberFilterAction(this, false);
308 fShowQualifiedTypeNamesAction= new ShowQualifiedTypeNamesAction(this, false);
309
310 fFocusOnTypeAction= new FocusOnTypeAction(this);
311
312 fToggleLinkingAction= new ToggleLinkingAction(this);
313 fToggleLinkingAction.setActionDefinitionId(IWorkbenchCommandConstants.NAVIGATE_TOGGLE_LINK_WITH_EDITOR);
314
315 fPaneLabelProvider= new JavaUILabelProvider();
316
317 fFocusOnSelectionAction= new FocusOnSelectionAction(this);
318
319 fPartListener= new IPartListener2() {
320 public void partVisible(IWorkbenchPartReference ref) {
321 IWorkbenchPart part= ref.getPart(false);
322 if (part == TypeHierarchyViewPart.this) {
323 visibilityChanged(true);
324 }
325 }
326
327 public void partHidden(IWorkbenchPartReference ref) {
328 IWorkbenchPart part= ref.getPart(false);
329 if (part == TypeHierarchyViewPart.this) {
330 visibilityChanged(false);
331 }
332 }
333
334 public void partActivated(IWorkbenchPartReference ref) {
335 IWorkbenchPart part= ref.getPart(false);
336 if (part instanceof IEditorPart)
337 editorActivated((IEditorPart) part);
338 }
339
340 public void partInputChanged(IWorkbenchPartReference ref) {
341 IWorkbenchPart part= ref.getPart(false);
342 if (part instanceof IEditorPart)
343 editorActivated((IEditorPart) part);
344 }
345
346 public void partBroughtToTop(IWorkbenchPartReference ref) {}
347 public void partClosed(IWorkbenchPartReference ref) {}
348 public void partDeactivated(IWorkbenchPartReference ref) {}
349 public void partOpened(IWorkbenchPartReference ref) {}
350 };
351
352 fSelectionChangedListener= new ISelectionChangedListener() {
353 public void selectionChanged(SelectionChangedEvent event) {
354 doSelectionChanged(event);
355 }
356 };
357 }
358
359 protected void doPropertyChange(PropertyChangeEvent event) {
360 String property= event.getProperty();
361 if (fMethodsViewer != null) {
362 if (MembersOrderPreferenceCache.isMemberOrderProperty(event.getProperty())) {
363 fMethodsViewer.refresh();
364 }
365 }
366 if (IWorkingSetManager.CHANGE_WORKING_SET_CONTENT_CHANGE.equals(property)) {
367 updateHierarchyViewer(true);
368 updateToolTipAndDescription();
369 }
370 }
371
372 /**
373 * Adds the entry if new. Inserted at the beginning of the history entries list.
374 * @param entry The new entry
375 */
376 private void addHistoryEntry(IJavaElement[] entry) {
377 for (Iterator<IJavaElement[]> iter= fInputHistory.iterator(); iter.hasNext();) {
378 IJavaElement[] elem= iter.next();
379 if (Arrays.equals(elem, entry)) {
380 fInputHistory.remove(elem);
381 break;
382 }
383 }
384 fInputHistory.add(0, entry);
385 fHistoryDropDownAction.setEnabled(true);
386 }
387
388 private void updateHistoryEntries() {
389 for (int i= fInputHistory.size() - 1; i >= 0; i--) {
390 IJavaElement[] entries= fInputHistory.get(i);
391 for (int j= 0; j < entries.length; j++) {
392 IJavaElement elem= entries[j];
393 if (elem != null && !elem.exists()) {
394 fInputHistory.remove(i);
395 break;
396 }
397 }
398 }
399 fHistoryDropDownAction.setEnabled(!fInputHistory.isEmpty());
400 }
401
402 /**
403 * Goes to the selected entry, without updating the order of history entries.
404 *
405 * @param entry the entry to open
406 */
407 public void gotoHistoryEntry(IJavaElement[] entry) {
408 if (fInputHistory.contains(entry)) {
409 updateInput(entry);
410 }
411 }
412
413 /**
414 * Gets all history entries.
415 * @return All history entries
416 */
417 public List<IJavaElement[]> getHistoryEntries() {
418 if (fInputHistory.size() > 0) {
419 updateHistoryEntries();
420 }
421 return fInputHistory;
422 }
423
424 /**
425 * Sets the history entries.
426 *
427 * @param elems the history elements to set
428 */
429 public void setHistoryEntries(IJavaElement[] elems) {
430 List<IJavaElement[]> list= new ArrayList<IJavaElement[]>(1);
431 list.add(elems);
432 setHistoryEntries(list);
433 }
434
435 /**
436 * Sets the history entries.
437 *
438 * @param elems the history elements to set
439 * @since 3.7
440 */
441 public void setHistoryEntries(List<IJavaElement[]> elems) {
442 fInputHistory.clear();
443 for (Iterator<IJavaElement[]> iterator= elems.iterator(); iterator.hasNext();) {
444 IJavaElement[] elements= iterator.next();
445 if (elements != null && elements.length != 0)
446 fInputHistory.add(elements);
447 }
448 updateHistoryEntries();
449 }
450
451 /**
452 * Selects an member in the methods list or in the current hierarchy.
453 * @param member The member to select
454 */
455 public void selectMember(IMember member) {
456 fSelectInEditor= false;
457 if (member.getElementType() != IJavaElement.TYPE) {
458 Control methodControl= fMethodsViewer.getControl();
459 if (methodControl != null && !methodControl.isDisposed()) {
460 methodControl.setFocus();
461 }
462
463 fMethodsViewer.setSelection(new StructuredSelection(member), true);
464 } else {
465 Control viewerControl= getCurrentViewer().getControl();
466 if (viewerControl != null && !viewerControl.isDisposed()) {
467 viewerControl.setFocus();
468 }
469
470 if (!member.equals(fSelectedType)) {
471 getCurrentViewer().setSelection(new StructuredSelection(member), true);
472 }
473 }
474 fSelectInEditor= true;
475 }
476
477 /**
478 * {@inheritDoc}
479 *
480 * @deprecated use getInputElement instead
481 */
482 public IType getInput() {
483 if (fInputElements.length == 1 && fInputElements[0] instanceof IType) {
484 return (IType)fInputElements[0];
485 }
486 return null;
487 }
488
489 /**
490 * {@inheritDoc}
491 *
492 * @deprecated use setInputElement instead
493 */
494 public void setInput(IType type) {
495 setInputElement(type);
496 }
497
498 /**
499 * Returns the input element of the type hierarchy. Can be of type <code>IType</code> or
500 * <code>IPackageFragment</code>
501 *
502 * @return the input element
503 */
504 public IJavaElement getInputElement() {
505 return fInputElements == null ? null : (fInputElements.length == 1 ? fInputElements[0] : null);
506 }
507
508 /**
509 * Returns the input elements of the type hierarchy.
510 *
511 * @return the input elements
512 * @since 3.7
513 */
514 public IJavaElement[] getInputElements() {
515 return fInputElements;
516 }
517
518
519 /**
520 * Sets the input to a new element.
521 * @param element the input element
522 */
523 public void setInputElement(IJavaElement element) {
524 setInputElements(element == null ? null : new IJavaElement[] { element });
525 }
526
527
528 /**
529 * Sets the input to a new element.
530 *
531 * @param javaElements the input java elements
532 * @since 3.7
533 */
534 public void setInputElements(IJavaElement[] javaElements) {
535 IJavaElement[] newElements= null;
536 IMember memberToSelect= null;
537 if (javaElements != null) {
538 newElements= new IJavaElement[javaElements.length];
539 for (int i= 0; i < javaElements.length; i++) {
540 newElements[i]= javaElements[i];
541 memberToSelect= null;
542 if (newElements[i] != null) {
543 if (newElements[i] instanceof IMember) {
544 if (newElements[i].getElementType() != IJavaElement.TYPE) {
545 memberToSelect= (IMember)newElements[i];
546 newElements[i]= memberToSelect.getDeclaringType();
547 }
548 if (!newElements[i].exists()) {
549 MessageDialog.openError(getSite().getShell(), TypeHierarchyMessages.TypeHierarchyViewPart_error_title, TypeHierarchyMessages.TypeHierarchyViewPart_error_message);
550 return;
551 }
552 } else {
553 int kind= newElements[i].getElementType();
554 if (kind != IJavaElement.JAVA_PROJECT && kind != IJavaElement.PACKAGE_FRAGMENT_ROOT && kind != IJavaElement.PACKAGE_FRAGMENT) {
555 newElements= null;
556 JavaPlugin.logErrorMessage("Invalid type hierarchy input type.");//$NON-NLS-1$
557 return;
558 }
559 }
560 }
561 }
562 if (!javaElements.equals(fInputElements)) {
563 addHistoryEntry(javaElements);
564 }
565 }
566 updateInput(newElements);
567 if (memberToSelect != null) {
568 selectMember(memberToSelect);
569 }
570 }
571
572 /*
573 * Changes the input to a new type
574 * @param inputElement
575 */
576 private void updateInput(IJavaElement[] inputElements) {
577 IJavaElement[] prevInput= fInputElements;
578
579 synchronized (this) {
580 if (fRestoreStateJob != null) {
581 fRestoreStateJob.cancel();
582 fRestoreJobCanceledExplicitly= false;
583 try {
584 fRestoreStateJob.join();
585 } catch (InterruptedException e) {
586 // ignore
587 } finally {
588 fRestoreStateJob= null;
589 }
590 }
591 }
592
593 // Make sure the UI got repainted before we execute a long running
594 // operation. This can be removed if we refresh the hierarchy in a
595 // separate thread.
596 // Work-around for http://dev.eclipse.org/bugs/show_bug.cgi?id=30881
597 processOutstandingEvents();
598 if (inputElements == null) {
599 clearInput();
600 } else {
601 if (!inputElements.equals(prevInput)) {
602 for (int i= 0; i < fAllViewers.length; i++) {
603 fAllViewers[i].setInput(null);
604 }
605 }
606 fInputElements= inputElements;
607 fNoHierarchyShownLabel
608 .setText(Messages.format(TypeHierarchyMessages.TypeHierarchyViewPart_createinput, HistoryAction.getElementLabel(fInputElements)));
609 try {
610 fHierarchyLifeCycle.ensureRefreshedTypeHierarchy(inputElements, JavaPlugin.getActiveWorkbenchWindow());
611 // fHierarchyLifeCycle.ensureRefreshedTypeHierarchy(inputElement, getSite().getWorkbenchWindow());
612 } catch (InvocationTargetException e) {
613 ExceptionHandler.handle(e, getSite().getShell(), TypeHierarchyMessages.TypeHierarchyViewPart_exception_title, TypeHierarchyMessages.TypeHierarchyViewPart_exception_message);
614 clearInput();
615 return;// panic code. This code wont be executed.
616 } catch (InterruptedException e) {
617 fNoHierarchyShownLabel.setText(TypeHierarchyMessages.TypeHierarchyViewPart_empty);
618 return;// panic code. This code wont be executed.
619 }
620
621 if (inputElements.length == 1 && inputElements[0].getElementType() != IJavaElement.TYPE) {
622 setHierarchyMode(HIERARCHY_MODE_CLASSIC);
623 }
624 updateViewers();
625 }
626 }
627
628 /**
629 * Updates the viewers, toolbar buttons and tooltip.
630 *
631 * @since 3.6
632 */
633 public void updateViewers() {
634 if (fInputElements == null)
635 return;
636 if (!fHierarchyLifeCycle.isRefreshJobRunning()) {
637 setViewersInput();
638 }
639 setViewerVisibility(true);
640 // turn off member filtering
641 fSelectInEditor= false;
642 setMemberFilter(null);
643 internalSelectType(null, false); // clear selection
644 fIsEnableMemberFilter= false;
645 updateHierarchyViewer(true);
646 IType root= getSelectableType(fInputElements);
647 internalSelectType(root, true);
648 updateMethodViewer(root);
649 updateToolbarButtons();
650 updateToolTipAndDescription();
651 showMembersInHierarchy(false);
652 fPagebook.showPage(fTypeMethodsSplitter);
653 fSelectInEditor= true;
654 }
655
656 private void processOutstandingEvents() {
657 Display display= getDisplay();
658 if (display != null && !display.isDisposed())
659 display.update();
660 }
661
662 private void clearInput() {
663 fInputElements= null;
664 fHierarchyLifeCycle.freeHierarchy();
665
666 updateHierarchyViewer(false);
667 updateToolbarButtons();
668 updateToolTipAndDescription();
669 getViewSite().getActionBars().getStatusLineManager().setMessage(""); //$NON-NLS-1$
670 }
671
672 /*
673 * @see IWorbenchPart#setFocus
674 */
675 @Override
676 public void setFocus() {
677 fPagebook.setFocus();
678 }
679
680 /*
681 * @see IWorkbenchPart#dispose
682 */
683 @Override
684 public void dispose() {
685 if (fHierarchyLifeCycle != null) {
686 fHierarchyLifeCycle.freeHierarchy();
687 fHierarchyLifeCycle.removeChangedListener(fTypeHierarchyLifeCycleListener);
688 fHierarchyLifeCycle= null;
689 }
690 fPaneLabelProvider.dispose();
691
692 if (fMethodsViewer != null) {
693 fMethodsViewer.dispose();
694 }
695
696 if (fPropertyChangeListener != null) {
697 JavaPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(fPropertyChangeListener);
698 fPropertyChangeListener= null;
699 }
700
701 getSite().getPage().removePartListener(fPartListener);
702
703 if (fActionGroups != null)
704 fActionGroups.dispose();
705
706 if (fWorkingSetActionGroup != null)
707 fWorkingSetActionGroup.dispose();
708
709 super.dispose();
710 }
711
712 /* (non-Javadoc)
713 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
714 */
715 @Override
716 public Object getAdapter(Class key) {
717 if (key == IShowInSource.class) {
718 return getShowInSource();
719 }
720 if (key == IShowInTargetList.class) {
721 return new IShowInTargetList() {
722 public String[] getShowInTargetIds() {
723 return new String[] { JavaUI.ID_PACKAGES, JavaPlugin.ID_RES_NAV };
724 }
725
726 };
727 }
728 if (key == IContextProvider.class) {
729 return JavaUIHelp.getHelpContextProvider(this, IJavaHelpContextIds.TYPE_HIERARCHY_VIEW);
730 }
731 return super.getAdapter(key);
732 }
733
734 private Control createTypeViewerControl(Composite parent) {
735 fViewerbook= new PageBook(parent, SWT.NULL);
736
737 KeyListener keyListener= createKeyListener();
738
739 // Create the viewers
740 TypeHierarchyViewer superTypesViewer= new SuperTypeHierarchyViewer(fViewerbook, fHierarchyLifeCycle);
741 initializeTypesViewer(superTypesViewer, keyListener, IContextMenuConstants.TARGET_ID_SUPERTYPES_VIEW);
742
743 TypeHierarchyViewer subTypesViewer= new SubTypeHierarchyViewer(fViewerbook, fHierarchyLifeCycle);
744 initializeTypesViewer(subTypesViewer, keyListener, IContextMenuConstants.TARGET_ID_SUBTYPES_VIEW);
745
746 TypeHierarchyViewer vajViewer= new TraditionalHierarchyViewer(fViewerbook, fHierarchyLifeCycle);
747 initializeTypesViewer(vajViewer, keyListener, IContextMenuConstants.TARGET_ID_HIERARCHY_VIEW);
748
749 fAllViewers= new TypeHierarchyViewer[3];
750 fAllViewers[HIERARCHY_MODE_SUPERTYPES]= superTypesViewer;
751 fAllViewers[HIERARCHY_MODE_SUBTYPES]= subTypesViewer;
752 fAllViewers[HIERARCHY_MODE_CLASSIC]= vajViewer;
753
754 int currViewerIndex;
755 try {
756 currViewerIndex= fDialogSettings.getInt(DIALOGSTORE_HIERARCHYVIEW);
757 if (currViewerIndex < 0 || currViewerIndex > 2) {
758 currViewerIndex= HIERARCHY_MODE_CLASSIC;
759 }
760 } catch (NumberFormatException e) {
761 currViewerIndex= HIERARCHY_MODE_CLASSIC;
762 }
763
764 fEmptyTypesViewer= new Label(fViewerbook, SWT.TOP | SWT.LEFT | SWT.WRAP);
765
766 for (int i= 0; i < fAllViewers.length; i++) {
767 fAllViewers[i].setInput(fAllViewers[i]);
768 }
769
770 // force the update
771 fCurrentViewerIndex= -1;
772 setHierarchyMode(currViewerIndex);
773
774 return fViewerbook;
775 }
776
777 private KeyListener createKeyListener() {
778 return new KeyAdapter() {
779 @Override
780 public void keyReleased(KeyEvent event) {
781 if (event.stateMask == 0) {
782 if (event.keyCode == SWT.F5) {
783 ITypeHierarchy hierarchy= fHierarchyLifeCycle.getHierarchy();
784 if (hierarchy != null) {
785 fHierarchyLifeCycle.typeHierarchyChanged(hierarchy);
786 doTypeHierarchyChangedOnViewers(null);
787 }
788 updateHierarchyViewer(false);
789 return;
790 }
791 }
792 }
793 };
794 }
795
796
797 private void initializeTypesViewer(final TypeHierarchyViewer typesViewer, KeyListener keyListener, String cotextHelpId) {
798 typesViewer.getControl().setVisible(false);
799 typesViewer.getControl().addKeyListener(keyListener);
800 typesViewer.initContextMenu(new IMenuListener() {
801 public void menuAboutToShow(IMenuManager menu) {
802 fillTypesViewerContextMenu(typesViewer, menu);
803 }
804 }, cotextHelpId, getSite());
805 typesViewer.addPostSelectionChangedListener(fSelectionChangedListener);
806 typesViewer.setQualifiedTypeName(isQualifiedTypeNamesEnabled());
807 typesViewer.setWorkingSetFilter(fWorkingSetActionGroup.getWorkingSetFilter());
808 }
809
810 private Control createMethodViewerControl(Composite parent) {
811 fMethodsViewer= new MethodsViewer(parent, fHierarchyLifeCycle);
812 fMethodsViewer.initContextMenu(new IMenuListener() {
813 public void menuAboutToShow(IMenuManager menu) {
814 fillMethodsViewerContextMenu(menu);
815 }
816 }, IContextMenuConstants.TARGET_ID_MEMBERS_VIEW, getSite());
817 fMethodsViewer.addPostSelectionChangedListener(fSelectionChangedListener);
818
819 new OpenAndLinkWithEditorHelper(fMethodsViewer) {
820 @Override
821 protected void activate(ISelection selection) {
822 try {
823 final Object selectedElement= SelectionUtil.getSingleElement(selection);
824 if (EditorUtility.isOpenInEditor(selectedElement) != null)
825 EditorUtility.openInEditor(selectedElement, true);
826 } catch (PartInitException ex) {
827 // ignore if no editor input can be found
828 }
829 }
830
831 @Override
832 protected void linkToEditor(ISelection selection) {
833 // do nothing: this is handled in more detail by the part itself
834 }
835
836 @Override
837 protected void open(ISelection selection, boolean activate) {
838 if (selection instanceof IStructuredSelection)
839 fOpenAction.run((IStructuredSelection)selection);
840 }
841 };
842
843 Control control= fMethodsViewer.getTable();
844 control.addKeyListener(createKeyListener());
845 control.addFocusListener(new FocusListener() {
846 public void focusGained(FocusEvent e) {
847 fSelectAllAction.setEnabled(true);
848 }
849
850 public void focusLost(FocusEvent e) {
851 fSelectAllAction.setEnabled(false);
852 }
853 });
854
855 return control;
856 }
857
858 private void initDragAndDrop() {
859 for (int i= 0; i < fAllViewers.length; i++) {
860 addDragAdapters(fAllViewers[i]);
861 addDropAdapters(fAllViewers[i]);
862 }
863 addDragAdapters(fMethodsViewer);
864 fMethodsViewer.addDropSupport(DND.DROP_NONE, new Transfer[0], new DropTargetAdapter());
865
866 //DND on empty hierarchy
867 DropTarget dropTarget = new DropTarget(fPagebook, DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_LINK | DND.DROP_DEFAULT);
868 dropTarget.setTransfer(new Transfer[] { LocalSelectionTransfer.getInstance() });
869 dropTarget.addDropListener(new TypeHierarchyTransferDropAdapter(this, fAllViewers[0]));
870 }
871
872 private void addDropAdapters(AbstractTreeViewer viewer) {
873 Transfer[] transfers= new Transfer[] { LocalSelectionTransfer.getInstance(), PluginTransfer.getInstance() };
874 int ops= DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_LINK | DND.DROP_DEFAULT;
875
876 DelegatingDropAdapter delegatingDropAdapter= new DelegatingDropAdapter();
877 delegatingDropAdapter.addDropTargetListener(new TypeHierarchyTransferDropAdapter(this, viewer));
878 delegatingDropAdapter.addDropTargetListener(new PluginTransferDropAdapter(viewer));
879
880 viewer.addDropSupport(ops, transfers, delegatingDropAdapter);
881 }
882
883 private void addDragAdapters(StructuredViewer viewer) {
884 int ops= DND.DROP_COPY | DND.DROP_LINK;
885 Transfer[] transfers= new Transfer[] { LocalSelectionTransfer.getInstance(), ResourceTransfer.getInstance(), FileTransfer.getInstance()};
886
887 JdtViewerDragAdapter dragAdapter= new JdtViewerDragAdapter(viewer);
888 dragAdapter.addDragSourceListener(new SelectionTransferDragAdapter(viewer));
889 dragAdapter.addDragSourceListener(new EditorInputTransferDragAdapter(viewer));
890 dragAdapter.addDragSourceListener(new ResourceTransferDragAdapter(viewer));
891 dragAdapter.addDragSourceListener(new FileTransferDragAdapter(viewer));
892
893 viewer.addDragSupport(ops, transfers, dragAdapter);
894 }
895
896 /**
897 * Returns the inner component in a workbench part.
898 * @see IWorkbenchPart#createPartControl(Composite)
899 */
900 @Override
901 public void createPartControl(Composite container) {
902 fParent= container;
903 addResizeListener(container);
904
905 fPagebook= new PageBook(container, SWT.NONE);
906 fWorkingSetActionGroup= new WorkingSetFilterActionGroup(getSite(), fPropertyChangeListener);
907
908 // page 1 of page book (no hierarchy label)
909
910 fNoHierarchyShownLabel= new Label(fPagebook, SWT.TOP + SWT.LEFT + SWT.WRAP);
911 fNoHierarchyShownLabel.setText(TypeHierarchyMessages.TypeHierarchyViewPart_empty);
912
913 // page 2 of page book (viewers)
914
915 fTypeMethodsSplitter= new SashForm(fPagebook, SWT.VERTICAL);
916 fTypeMethodsSplitter.setVisible(false);
917
918 fTypeViewerViewForm= new ViewForm(fTypeMethodsSplitter, SWT.NONE);
919
920 Control typeViewerControl= createTypeViewerControl(fTypeViewerViewForm);
921 fTypeViewerViewForm.setContent(typeViewerControl);
922
923 fMethodViewerViewForm= new ViewForm(fTypeMethodsSplitter, SWT.NONE);
924 fTypeMethodsSplitter.setWeights(new int[] {35, 65});
925
926 Control methodViewerPart= createMethodViewerControl(fMethodViewerViewForm);
927 fMethodViewerViewForm.setContent(methodViewerPart);
928
929 fMethodViewerPaneLabel= new CLabel(fMethodViewerViewForm, SWT.NONE);
930 fMethodViewerViewForm.setTopLeft(fMethodViewerPaneLabel);
931
932 ToolBar methodViewerToolBar= new ToolBar(fMethodViewerViewForm, SWT.FLAT | SWT.WRAP);
933 fMethodViewerViewForm.setTopCenter(methodViewerToolBar);
934
935 initDragAndDrop();
936
937 MenuManager menu= new MenuManager();
938 menu.add(fFocusOnTypeAction);
939 fNoHierarchyShownLabel.setMenu(menu.createContextMenu(fNoHierarchyShownLabel));
940
941 fPagebook.showPage(fNoHierarchyShownLabel);
942
943 int layout;
944 try {
945 layout= fDialogSettings.getInt(DIALOGSTORE_VIEWLAYOUT);
946 if (layout < 0 || layout > 3) {
947 layout= VIEW_LAYOUT_AUTOMATIC;
948 }
949 } catch (NumberFormatException e) {
950 layout= VIEW_LAYOUT_AUTOMATIC;
951 }
952 // force the update
953 fCurrentLayout= -1;
954 // will fill the main tool bar
955 setViewLayout(layout);
956
957 showQualifiedTypeNames(fDialogSettings.getBoolean(DIALOGSTORE_QUALIFIED_NAMES));
958 setLinkingEnabled(fDialogSettings.getBoolean(DIALOGSTORE_LINKEDITORS));
959
960 // set the filter menu items
961 IActionBars actionBars= getViewSite().getActionBars();
962 IMenuManager viewMenu= actionBars.getMenuManager();
963 for (int i= 0; i < fViewActions.length; i++) {
964 ToggleViewAction action= fViewActions[i];
965 viewMenu.add(action);
966 action.setEnabled(false);
967 }
968 viewMenu.add(new Separator());
969
970 fWorkingSetActionGroup.fillViewMenu(viewMenu);
971
972 viewMenu.add(new Separator());
973
974 IMenuManager layoutSubMenu= new MenuManager(TypeHierarchyMessages.TypeHierarchyViewPart_layout_submenu);
975 viewMenu.add(layoutSubMenu);
976 for (int i= 0; i < fToggleOrientationActions.length; i++) {
977 layoutSubMenu.add(fToggleOrientationActions[i]);
978 }
979 viewMenu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
980 viewMenu.add(fShowQualifiedTypeNamesAction);
981 viewMenu.add(fToggleLinkingAction);
982
983
984 // fill the method viewer tool bar
985 ToolBarManager lowertbmanager= new ToolBarManager(methodViewerToolBar);
986 lowertbmanager.add(fEnableMemberFilterAction);
987 lowertbmanager.add(new Separator());
988 fMethodsViewer.contributeToToolBar(lowertbmanager);
989 lowertbmanager.update(true);
990
991 // selection provider
992 int nHierarchyViewers= fAllViewers.length;
993 StructuredViewer[] trackedViewers= new StructuredViewer[nHierarchyViewers + 1];
994 for (int i= 0; i < nHierarchyViewers; i++) {
995 trackedViewers[i]= fAllViewers[i];
996 }
997 trackedViewers[nHierarchyViewers]= fMethodsViewer;
998 fSelectionProviderMediator= new SelectionProviderMediator(trackedViewers, getCurrentViewer());
999 IStatusLineManager slManager= getViewSite().getActionBars().getStatusLineManager();
1000 fSelectionProviderMediator.addSelectionChangedListener(new StatusBarUpdater(slManager));
1001
1002 getSite().setSelectionProvider(fSelectionProviderMediator);
1003 getSite().getPage().addPartListener(fPartListener);
1004
1005 if (fMemento != null)
1006 restoreState(fMemento);
1007 else
1008 setViewerVisibility(false);
1009
1010 PlatformUI.getWorkbench().getHelpSystem().setHelp(fPagebook, IJavaHelpContextIds.TYPE_HIERARCHY_VIEW);
1011
1012
1013 fActionGroups= new CompositeActionGroup(new ActionGroup[] {
1014 new NewWizardsActionGroup(this.getSite()),
1015 new OpenEditorActionGroup(this),
1016 new OpenViewActionGroup(this),
1017 new CCPActionGroup(this),
1018 new GenerateActionGroup(this),
1019 new RefactorActionGroup(this),
1020 new JavaSearchActionGroup(this)
1021 });
1022
1023 fActionGroups.fillActionBars(actionBars);
1024 fSelectAllAction= new SelectAllAction(fMethodsViewer);
1025 fOpenAction= new OpenAction(getSite());
1026
1027 actionBars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(), fSelectAllAction);
1028
1029 IHandlerService handlerService= (IHandlerService) getViewSite().getService(IHandlerService.class);
1030 handlerService.activateHandler(IWorkbenchCommandConstants.NAVIGATE_TOGGLE_LINK_WITH_EDITOR, new ActionHandler(fToggleLinkingAction));
1031 }
1032
1033 private void addResizeListener(Composite parent) {
1034 parent.addControlListener(new ControlListener() {
1035 public void controlMoved(ControlEvent e) {
1036 }
1037 public void controlResized(ControlEvent e) {
1038 int viewLayout= getViewLayout();
1039 if ((viewLayout == VIEW_LAYOUT_AUTOMATIC || viewLayout == -1) && !fInComputeLayout) {
1040 setViewLayout(VIEW_LAYOUT_AUTOMATIC);
1041 }
1042 }
1043 });
1044 }
1045
1046 /* (non-Javadoc)
1047 * @see org.eclipse.jdt.ui.ITypeHierarchyViewPart#setViewLayout(int)
1048 */
1049 public void setViewLayout(int layout) {
1050 if (fCurrentLayout != layout || layout == VIEW_LAYOUT_AUTOMATIC) {
1051 fInComputeLayout= true;
1052 try {
1053 boolean methodViewerNeedsUpdate= false;
1054
1055 if (fMethodViewerViewForm != null && !fMethodViewerViewForm.isDisposed()
1056 && fTypeMethodsSplitter != null && !fTypeMethodsSplitter.isDisposed()) {
1057
1058 boolean horizontal= false;
1059 if (layout == VIEW_LAYOUT_SINGLE) {
1060 fMethodViewerViewForm.setVisible(false);
1061 showMembersInHierarchy(false);
1062 updateMethodViewer(null);
1063 } else {
1064 if (fCurrentLayout == VIEW_LAYOUT_SINGLE) {
1065 fMethodViewerViewForm.setVisible(true);
1066 methodViewerNeedsUpdate= true;
1067 }
1068 if (layout == VIEW_LAYOUT_AUTOMATIC) {
1069 if (fParent != null && !fParent.isDisposed()) {
1070 Point size= fParent.getSize();
1071 if (size.x != 0 && size.y != 0) {
1072 // bug 185397 - Hierarchy View flips orientation multiple times on resize
1073 Control viewFormToolbar= fTypeViewerViewForm.getTopLeft();
1074 if (viewFormToolbar != null && !viewFormToolbar.isDisposed() && viewFormToolbar.isVisible()) {
1075 size.y -= viewFormToolbar.getSize().y;
1076 }
1077 horizontal= size.x > size.y;
1078 } else if (size.x == 0 && size.y == 0) {
1079 return;
1080 }
1081 }
1082 if (fCurrentLayout == VIEW_LAYOUT_AUTOMATIC) {
1083 boolean wasHorizontal= fTypeMethodsSplitter.getOrientation() == SWT.HORIZONTAL;
1084 if (wasHorizontal == horizontal) {
1085 return; // no real change
1086 }
1087 }
1088
1089 } else if (layout == VIEW_LAYOUT_HORIZONTAL) {
1090 horizontal= true;
1091 }
1092 fTypeMethodsSplitter.setOrientation(horizontal ? SWT.HORIZONTAL : SWT.VERTICAL);
1093 }
1094 updateMainToolbar(horizontal);
1095 fTypeMethodsSplitter.layout();
1096 }
1097 if (methodViewerNeedsUpdate) {
1098 updateMethodViewer(fSelectedType);
1099 }
1100 fDialogSettings.put(DIALOGSTORE_VIEWLAYOUT, layout);
1101 fCurrentLayout= layout;
1102
1103 updateCheckedState();
1104 } finally {
1105 fInComputeLayout= false;
1106 }
1107 }
1108 }
1109
1110 /* (non-Javadoc)
1111 * @see org.eclipse.jdt.ui.ITypeHierarchyViewPart#getViewLayout()
1112 */
1113 public int getViewLayout() {
1114 return fCurrentLayout;
1115 }
1116
1117 private void updateCheckedState() {
1118 for (int i= 0; i < fToggleOrientationActions.length; i++) {
1119 fToggleOrientationActions[i].setChecked(getViewLayout() == fToggleOrientationActions[i].getOrientation());
1120 }
1121 }
1122
1123 private void updateMainToolbar(boolean horizontal) {
1124 IActionBars actionBars= getViewSite().getActionBars();
1125 IToolBarManager tbmanager= actionBars.getToolBarManager();
1126
1127 if (horizontal) {
1128 clearMainToolBar(tbmanager);
1129 ToolBar typeViewerToolBar= new ToolBar(fTypeViewerViewForm, SWT.FLAT | SWT.WRAP);
1130 fillMainToolBar(new ToolBarManager(typeViewerToolBar));
1131 fTypeViewerViewForm.setTopLeft(typeViewerToolBar);
1132 } else {
1133 fTypeViewerViewForm.setTopLeft(null);
1134 fillMainToolBar(tbmanager);
1135 }
1136 }
1137
1138 private void fillMainToolBar(IToolBarManager tbmanager) {
1139 tbmanager.removeAll();
1140 for (int i= 0; i < fViewActions.length; i++) {
1141 tbmanager.add(fViewActions[i]);
1142 }
1143 tbmanager.add(fHistoryDropDownAction);
1144 tbmanager.update(false);
1145 }
1146
1147 private void clearMainToolBar(IToolBarManager tbmanager) {
1148 tbmanager.removeAll();
1149 tbmanager.update(false);
1150 }
1151
1152
1153 /*
1154 * Creates the context menu for the hierarchy viewers
1155 */
1156 private void fillTypesViewerContextMenu(TypeHierarchyViewer viewer, IMenuManager menu) {
1157 JavaPlugin.createStandardGroups(menu);
1158
1159 menu.appendToGroup(IContextMenuConstants.GROUP_SHOW, new Separator(GROUP_FOCUS));
1160 // viewer entries
1161 viewer.contributeToContextMenu(menu);
1162
1163 if (fFocusOnSelectionAction.canActionBeAdded())
1164 menu.appendToGroup(GROUP_FOCUS, fFocusOnSelectionAction);
1165 menu.appendToGroup(GROUP_FOCUS, fFocusOnTypeAction);
1166
1167 fActionGroups.setContext(new ActionContext(getSite().getSelectionProvider().getSelection()));
1168 fActionGroups.fillContextMenu(menu);
1169 fActionGroups.setContext(null);
1170 }
1171
1172 /*
1173 * Creates the context menu for the method viewer
1174 */
1175 private void fillMethodsViewerContextMenu(IMenuManager menu) {
1176 JavaPlugin.createStandardGroups(menu);
1177 // viewer entries
1178 fMethodsViewer.contributeToContextMenu(menu);
1179 fActionGroups.setContext(new ActionContext(getSite().getSelectionProvider().getSelection()));
1180 fActionGroups.fillContextMenu(menu);
1181 fActionGroups.setContext(null);
1182 }
1183
1184 /*
1185 * Toggles between the empty viewer page and the hierarchy
1186 */
1187 private void setViewerVisibility(boolean showHierarchy) {
1188 if (showHierarchy) {
1189 fViewerbook.showPage(getCurrentViewer().getControl());
1190 } else {
1191 fViewerbook.showPage(fEmptyTypesViewer);
1192 }
1193 }
1194
1195 /*
1196 * Sets the member filter. <code>null</code> disables member filtering.
1197 */
1198 private void setMemberFilter(IMember[] memberFilter) {
1199 Assert.isNotNull(fAllViewers);
1200 for (int i= 0; i < fAllViewers.length; i++) {
1201 fAllViewers[i].setMemberFilter(memberFilter);
1202 }
1203 }
1204
1205 private IType getSelectableType(IJavaElement[] elem) {
1206 if (elem[0].getElementType() != IJavaElement.TYPE) {
1207 return getCurrentViewer().getTreeRootType();
1208 } else {
1209 return (IType)elem[0];
1210 }
1211 }
1212
1213 private void internalSelectType(IMember elem, boolean reveal) {
1214 TypeHierarchyViewer viewer= getCurrentViewer();
1215 viewer.removePostSelectionChangedListener(fSelectionChangedListener);
1216 viewer.setSelection(elem != null ? new StructuredSelection(elem) : StructuredSelection.EMPTY, reveal);
1217 viewer.addPostSelectionChangedListener(fSelectionChangedListener);
1218 }
1219
1220 /*
1221 * When the input changed or the hierarchy pane becomes visible,
1222 * <code>updateHierarchyViewer<code> brings up the correct view and refreshes
1223 * the current tree
1224 */
1225 private void updateHierarchyViewer(final boolean doExpand) {
1226 if (fInputElements == null) {
1227 fNoHierarchyShownLabel.setText(TypeHierarchyMessages.TypeHierarchyViewPart_empty);
1228 fPagebook.showPage(fNoHierarchyShownLabel);
1229 } else {
1230 if (getCurrentViewer().containsElements() != null) {
1231 Runnable runnable= new Runnable() {
1232 public void run() {
1233 getCurrentViewer().updateContent(doExpand); // refresh
1234 }
1235 };
1236 BusyIndicator.showWhile(getDisplay(), runnable);
1237 if (!isChildVisible(fViewerbook, getCurrentViewer().getControl())) {
1238 setViewerVisibility(true);
1239 }
1240 } else if (!isKeepShowingEmptyViewers()) {//Show the empty hierarchy viewer till fresh computation is done.
1241 fEmptyTypesViewer.setText(Messages.format(TypeHierarchyMessages.TypeHierarchyViewPart_nodecl, HistoryAction.getElementLabel(fInputElements)));
1242 setViewerVisibility(false);
1243 }
1244 }
1245 }
1246
1247 private void updateMethodViewer(final IType input) {
1248 if (!fIsEnableMemberFilter && fCurrentLayout != VIEW_LAYOUT_SINGLE) {
1249 if (input == fMethodsViewer.getInput()) {
1250 if (input != null) {
1251 Runnable runnable= new Runnable() {
1252 public void run() {
1253 fMethodsViewer.refresh(); // refresh
1254 }
1255 };
1256 BusyIndicator.showWhile(getDisplay(), runnable);
1257 }
1258 } else {
1259 if (input != null) {
1260 fMethodViewerPaneLabel.setText(fPaneLabelProvider.getText(input));
1261 fMethodViewerPaneLabel.setImage(fPaneLabelProvider.getImage(input));
1262 } else {
1263 fMethodViewerPaneLabel.setText(""); //$NON-NLS-1$
1264 fMethodViewerPaneLabel.setImage(null);
1265 }
1266 Runnable runnable= new Runnable() {
1267 public void run() {
1268 fMethodsViewer.setInput(input); // refresh
1269 }
1270 };
1271 BusyIndicator.showWhile(getDisplay(), runnable);
1272 }
1273 }
1274 }
1275
1276 protected void doSelectionChanged(SelectionChangedEvent e) {
1277 if (e.getSelectionProvider() == fMethodsViewer) {
1278 methodSelectionChanged(e.getSelection());
1279 } else {
1280 typeSelectionChanged(e.getSelection());
1281 }
1282 }
1283
1284
1285
1286 private void methodSelectionChanged(ISelection sel) {
1287 if (sel instanceof IStructuredSelection) {
1288 List<?> selected= ((IStructuredSelection)sel).toList();
1289 int nSelected= selected.size();
1290 if (fIsEnableMemberFilter) {
1291 IMember[] memberFilter= null;
1292 if (nSelected > 0) {
1293 memberFilter= new IMember[nSelected];
1294 selected.toArray(memberFilter);
1295 }
1296 setMemberFilter(memberFilter);
1297 updateHierarchyViewer(true);
1298 updateToolTipAndDescription();
1299 internalSelectType(fSelectedType, true);
1300 }
1301 if (nSelected == 1 && fSelectInEditor) {
1302 revealElementInEditor(selected.get(0), fMethodsViewer);
1303 }
1304 }
1305 }
1306
1307 private void typeSelectionChanged(ISelection sel) {
1308 if (sel instanceof IStructuredSelection) {
1309 List<?> selected= ((IStructuredSelection)sel).toList();
1310 int nSelected= selected.size();
1311 if (nSelected != 0) {
1312 List<Object> types= new ArrayList<Object>(nSelected);
1313 for (int i= nSelected-1; i >= 0; i--) {
1314 Object elem= selected.get(i);
1315 if (elem instanceof IType && !types.contains(elem)) {
1316 types.add(elem);
1317 }
1318 }
1319 if (types.size() == 1) {
1320 fSelectedType= (IType) types.get(0);
1321 updateMethodViewer(fSelectedType);
1322 } else if (types.size() == 0) {
1323 // method selected, no change
1324 }
1325 if (nSelected == 1 && fSelectInEditor) {
1326 revealElementInEditor(selected.get(0), getCurrentViewer());
1327 }
1328 } else {
1329 fSelectedType= null;
1330 updateMethodViewer(null);
1331 }
1332 }
1333 }
1334
1335 private void revealElementInEditor(Object elem, StructuredViewer originViewer) {
1336 // only allow revealing when the type hierarchy is the active page
1337 // no revealing after selection events due to model changes
1338
1339 if (getSite().getPage().getActivePart() != this) {
1340 return;
1341 }
1342
1343 if (fSelectionProviderMediator.getViewerInFocus() != originViewer) {
1344 return;
1345 }
1346
1347 IEditorPart editorPart= EditorUtility.isOpenInEditor(elem);
1348 if (editorPart != null && (elem instanceof IJavaElement)) {
1349 getSite().getPage().removePartListener(fPartListener);
1350 getSite().getPage().bringToTop(editorPart);
1351 EditorUtility.revealInEditor(editorPart, (IJavaElement) elem);
1352 getSite().getPage().addPartListener(fPartListener);
1353 }
1354 }
1355
1356 private Display getDisplay() {
1357 if (fPagebook != null && !fPagebook.isDisposed()) {
1358 return fPagebook.getDisplay();
1359 }
1360 return null;
1361 }
1362
1363 private boolean isChildVisible(Composite pb, Control child) {
1364 Control[] children= pb.getChildren();
1365 for (int i= 0; i < children.length; i++) {
1366 if (children[i] == child && children[i].isVisible())
1367 return true;
1368 }
1369 return false;
1370 }
1371
1372 private void updateToolTipAndDescription() {
1373 String tooltip= ""; //$NON-NLS-1$
1374 String description;
1375 if (fInputElements != null && fInputElements.length != 0) {
1376 IWorkingSet workingSet= fWorkingSetActionGroup.getWorkingSet();
1377 String[] elementLabel= null;
1378 if (workingSet == null) {
1379 description= HistoryAction.getElementLabel(fInputElements);
1380 switch (fInputElements.length) {
1381 case 1:
1382 elementLabel= new String[] { HistoryAction.getShortLabel(fInputElements[0]) };
1383 tooltip= Messages.format(TypeHierarchyMessages.TypeHierarchyViewPart_tooltip, elementLabel);
1384 break;
1385 case 2:
1386 elementLabel= new String[] { HistoryAction.getShortLabel(fInputElements[0]), HistoryAction.getShortLabel(fInputElements[1]) };
1387 tooltip= Messages.format(TypeHierarchyMessages.TypeHierarchyViewPart_tooltip2, elementLabel);
1388 break;
1389 default:
1390 elementLabel= new String[] { HistoryAction.getShortLabel(fInputElements[0]), HistoryAction.getShortLabel(fInputElements[1]) };
1391 tooltip= Messages.format(TypeHierarchyMessages.TypeHierarchyViewPart_tooltip_more, elementLabel);
1392 }
1393 } else {
1394 switch (fInputElements.length) {
1395 case 1:
1396 elementLabel= new String[] { HistoryAction.getShortLabel(fInputElements[0]), workingSet.getLabel() };
1397 description= Messages.format(TypeHierarchyMessages.TypeHierarchyViewPart_ws_description, elementLabel);
1398 tooltip= Messages.format(TypeHierarchyMessages.TypeHierarchyViewPart_ws_tooltip, elementLabel);
1399 break;
1400 case 2:
1401 elementLabel= new String[] { HistoryAction.getShortLabel(fInputElements[0]), HistoryAction.getShortLabel(fInputElements[1]), workingSet.getLabel() };
1402 description= Messages.format(TypeHierarchyMessages.TypeHierarchyViewPart_ws_description2, elementLabel);
1403 tooltip= Messages.format(TypeHierarchyMessages.TypeHierarchyViewPart_ws_tooltip2, elementLabel);
1404 break;
1405 default:
1406 elementLabel= new String[] { HistoryAction.getShortLabel(fInputElements[0]), HistoryAction.getShortLabel(fInputElements[1]), workingSet.getLabel() };
1407 description= Messages.format(TypeHierarchyMessages.TypeHierarchyViewPart_ws_description_more, elementLabel);
1408 tooltip= Messages.format(TypeHierarchyMessages.TypeHierarchyViewPart_ws_tooltip_more, elementLabel);
1409 }
1410
1411 }
1412 } else {
1413 description= ""; //$NON-NLS-1$
1414 tooltip= getPartName();
1415 }
1416 setContentDescription(description);
1417 setTitleToolTip(tooltip);
1418 }
1419
1420 private void updateToolbarButtons() {
1421 boolean isNull= fInputElements == null;
1422 boolean isType= !isNull && fInputElements.length == 1 && fInputElements[0] instanceof IType;
1423 for (int i= 0; i < fViewActions.length; i++) {
1424 ToggleViewAction action= fViewActions[i];
1425 if (action.getViewerIndex() == HIERARCHY_MODE_CLASSIC) {
1426 action.setEnabled(!isNull);
1427 } else {
1428 action.setEnabled(isType);
1429 }
1430 }
1431 }
1432
1433
1434 public void setHierarchyMode(int viewerIndex) {
1435 Assert.isNotNull(fAllViewers);
1436 if (viewerIndex < fAllViewers.length && fCurrentViewerIndex != viewerIndex) {
1437
1438 fCurrentViewerIndex= viewerIndex;
1439
1440 updateHierarchyViewer(true);
1441 if (fInputElements != null) {
1442 ISelection currSelection= getCurrentViewer().getSelection();
1443 if (currSelection == null || currSelection.isEmpty()) {
1444 internalSelectType(getSelectableType(fInputElements), false);
1445 currSelection= getCurrentViewer().getSelection();
1446 }
1447 if (!fIsEnableMemberFilter) {
1448 typeSelectionChanged(currSelection);
1449 }
1450 }
1451 updateToolTipAndDescription();
1452
1453 fDialogSettings.put(DIALOGSTORE_HIERARCHYVIEW, viewerIndex);
1454 getCurrentViewer().getTree().setFocus();
1455
1456 if (fTypeOpenAndLinkWithEditorHelper != null)
1457 fTypeOpenAndLinkWithEditorHelper.dispose();
1458 fTypeOpenAndLinkWithEditorHelper= new OpenAndLinkWithEditorHelper(getCurrentViewer()) {
1459 @Override
1460 protected void activate(ISelection selection) {
1461 try {
1462 final Object selectedElement= SelectionUtil.getSingleElement(selection);
1463 if (EditorUtility.isOpenInEditor(selectedElement) != null)
1464 EditorUtility.openInEditor(selectedElement, true);
1465 } catch (PartInitException ex) {
1466 // ignore if no editor input can be found
1467 }
1468 }
1469
1470 @Override
1471 protected void linkToEditor(ISelection selection) {
1472 // do nothing: this is handled in more detailed by the part itself
1473 }
1474
1475 @Override
1476 protected void open(ISelection selection, boolean activate) {
1477 if (selection instanceof IStructuredSelection)
1478 fOpenAction.run((IStructuredSelection)selection);
1479 }
1480 };
1481
1482 }
1483 for (int i= 0; i < fViewActions.length; i++) {
1484 ToggleViewAction action= fViewActions[i];
1485 action.setChecked(fCurrentViewerIndex == action.getViewerIndex());
1486 }
1487 }
1488
1489 public int getHierarchyMode() {
1490 return fCurrentViewerIndex;
1491 }
1492
1493 private TypeHierarchyViewer getCurrentViewer() {
1494 return fAllViewers[fCurrentViewerIndex];
1495 }
1496
1497 /* (non-Javadoc)
1498 * @see org.eclipse.jdt.ui.ITypeHierarchyViewPart#showMembersInHierarchy(boolean)
1499 */
1500 public void showMembersInHierarchy(boolean on) {
1501 if (on != fIsEnableMemberFilter) {
1502 fIsEnableMemberFilter= on;
1503 if (!on) {
1504 IType methodViewerInput= (IType) fMethodsViewer.getInput();
1505 setMemberFilter(null);
1506 updateHierarchyViewer(true);
1507 updateToolTipAndDescription();
1508
1509 if (methodViewerInput != null && getCurrentViewer().isElementShown(methodViewerInput)) {
1510 // avoid that the method view changes content by selecting the previous input
1511 internalSelectType(methodViewerInput, true);
1512 } else if (fSelectedType != null) {
1513 // choose a input that exists
1514 internalSelectType(fSelectedType, true);
1515 updateMethodViewer(fSelectedType);
1516 }
1517 } else {
1518 methodSelectionChanged(fMethodsViewer.getSelection());
1519 }
1520 }
1521 fEnableMemberFilterAction.setChecked(on);
1522 }
1523
1524 /* (non-Javadoc)
1525 * @see org.eclipse.jdt.ui.ITypeHierarchyViewPart#isShowMembersInHierarchy()
1526 */
1527 public boolean isShowMembersInHierarchy() {
1528 return fIsEnableMemberFilter;
1529 }
1530
1531
1532 /* (non-Javadoc)
1533 * @see org.eclipse.jdt.ui.ITypeHierarchyViewPart#showQualifiedTypeNames(boolean)
1534 */
1535 public void showQualifiedTypeNames(boolean on) {
1536 if (on != fShowQualifiedTypeNames) {
1537 fShowQualifiedTypeNames= on;
1538 if (fAllViewers != null) {
1539 for (int i= 0; i < fAllViewers.length; i++) {
1540 fAllViewers[i].setQualifiedTypeName(on);
1541 }
1542 }
1543 }
1544 fShowQualifiedTypeNamesAction.setChecked(on);
1545 fDialogSettings.put(DIALOGSTORE_QUALIFIED_NAMES, on);
1546 }
1547
1548 /* (non-Javadoc)
1549 * @see org.eclipse.jdt.ui.ITypeHierarchyViewPart#isQualifiedTypeNamesEnabled()
1550 */
1551 public boolean isQualifiedTypeNamesEnabled() {
1552 return fShowQualifiedTypeNames;
1553 }
1554
1555 /**
1556 * Called from ITypeHierarchyLifeCycleListener.
1557 * Can be called from any thread
1558 * @param typeHierarchy Hierarchy that has changed
1559 * @param changedTypes Types in the hierarchy that have change or <code>null</code> if the full hierarchy has changed
1560 */
1561 protected void doTypeHierarchyChanged(final TypeHierarchyLifeCycle typeHierarchy, final IType[] changedTypes) {
1562 if (!fIsVisible) {
1563 fNeedRefresh= true;
1564 return;
1565 }
1566 if (fIsRefreshRunnablePosted) {
1567 return;
1568 }
1569
1570 Display display= getDisplay();
1571 if (display != null) {
1572 fIsRefreshRunnablePosted= true;
1573 display.asyncExec(new Runnable() {
1574 public void run() {
1575 try {
1576 if (fPagebook != null && !fPagebook.isDisposed()) {
1577 doTypeHierarchyChangedOnViewers(changedTypes);
1578 }
1579 } finally {
1580 fIsRefreshRunnablePosted= false;
1581 }
1582 }
1583 });
1584 }
1585 }
1586
1587 protected void doTypeHierarchyChangedOnViewers(IType[] changedTypes) {
1588 if (fHierarchyLifeCycle.getHierarchy() == null || !fHierarchyLifeCycle.getHierarchy().exists()) {
1589 clearInput();
1590 } else {
1591 if (changedTypes == null) {
1592 // hierarchy change
1593 try {
1594 fHierarchyLifeCycle.ensureRefreshedTypeHierarchy(fInputElements, getSite().getWorkbenchWindow());
1595 } catch (InvocationTargetException e) {
1596 ExceptionHandler.handle(e, getSite().getShell(), TypeHierarchyMessages.TypeHierarchyViewPart_exception_title, TypeHierarchyMessages.TypeHierarchyViewPart_exception_message);
1597 clearInput();
1598 return;
1599 } catch (InterruptedException e) {
1600 return;
1601 }
1602 fMethodsViewer.refresh();
1603 updateHierarchyViewer(false);
1604 } else {
1605 // elements in hierarchy modified
1606 Object methodViewerInput= fMethodsViewer.getInput();
1607 fMethodsViewer.refresh();
1608 fMethodViewerPaneLabel.setText(fPaneLabelProvider.getText(methodViewerInput));
1609 fMethodViewerPaneLabel.setImage(fPaneLabelProvider.getImage(methodViewerInput));
1610 if (getCurrentViewer().isMethodFiltering()) {
1611 if (changedTypes.length == 1) {
1612 getCurrentViewer().refresh(changedTypes[0]);
1613 } else {
1614 updateHierarchyViewer(false);
1615 }
1616 } else {
1617 getCurrentViewer().update(changedTypes, new String[] { IBasicPropertyConstants.P_TEXT, IBasicPropertyConstants.P_IMAGE } );
1618 }
1619 }
1620 }
1621 }
1622
1623 /*
1624 * @see IViewPart#init
1625 */
1626 @Override
1627 public void init(IViewSite site, IMemento memento) throws PartInitException {
1628 super.init(site, memento);
1629 fMemento= memento;
1630 }
1631
1632 /*
1633 * @see ViewPart#saveState(IMemento)
1634 */
1635 @Override
1636 public void saveState(IMemento memento) {
1637 if (fPagebook == null) {
1638 // part has not been created
1639 if (fMemento != null) { //Keep the old state;
1640 memento.putMemento(fMemento);
1641 }
1642 return;
1643 }
1644 if (fInputElements != null) {
1645 memento.putString(TAG_INPUT, fInputElements[0].getHandleIdentifier());
1646 for (int i= 1; i < fInputElements.length; i++) {
1647 IJavaElement element= fInputElements[i];
1648 memento.putString(TAG_INPUT + i, element.getHandleIdentifier());
1649 }
1650 }
1651 memento.putInteger(TAG_VIEW, getHierarchyMode());
1652 memento.putInteger(TAG_LAYOUT, getViewLayout());
1653 memento.putInteger(TAG_QUALIFIED_NAMES, isQualifiedTypeNamesEnabled() ? 1 : 0);
1654 memento.putInteger(TAG_EDITOR_LINKING, isLinkingEnabled() ? 1 : 0);
1655
1656 int weigths[]= fTypeMethodsSplitter.getWeights();
1657 int ratio= (weigths[0] * 1000) / (weigths[0] + weigths[1]);
1658 memento.putInteger(TAG_RATIO, ratio);
1659
1660 ScrollBar bar= getCurrentViewer().getTree().getVerticalBar();
1661 int position= bar != null ? bar.getSelection() : 0;
1662 memento.putInteger(TAG_VERTICAL_SCROLL, position);
1663
1664 IJavaElement selection= (IJavaElement)((IStructuredSelection) getCurrentViewer().getSelection()).getFirstElement();
1665 if (selection != null) {
1666 memento.putString(TAG_SELECTION, selection.getHandleIdentifier());
1667 }
1668
1669 fWorkingSetActionGroup.saveState(memento);
1670
1671 fMethodsViewer.saveState(memento);
1672 }
1673
1674 /*
1675 * Restores the type hierarchy settings from a memento.
1676 */
1677 private void restoreState(final IMemento memento) {
1678 IJavaElement input= null;
1679 List<IJavaElement> inputList= new ArrayList<IJavaElement>();
1680 String elementId= memento.getString(TAG_INPUT);
1681 int i= 0;
1682 while (elementId != null) {
1683 input= JavaCore.create(elementId);
1684 if (input == null || !input.exists()) {
1685 inputList= null;
1686 break;
1687 }
1688 inputList.add(input);
1689 elementId= memento.getString(TAG_INPUT + ++i);
1690 }
1691 if (inputList == null || inputList.size() == 0) {
1692 doRestoreState(memento, input);
1693 } else {
1694 final IJavaElement[] hierarchyInput= inputList.toArray(new IJavaElement[inputList.size()]);
1695
1696 synchronized (this) {
1697 String label= Messages.format(TypeHierarchyMessages.TypeHierarchyViewPart_restoreinput, HistoryAction.getElementLabel(hierarchyInput));
1698 fNoHierarchyShownLabel.setText(label);
1699
1700 fRestoreStateJob= new Job(label) {
1701 @Override
1702 protected IStatus run(IProgressMonitor monitor) {
1703 try {
1704 doRestoreInBackground(memento, hierarchyInput, monitor);
1705 } catch (JavaModelException e) {
1706 return e.getStatus();
1707 } catch (OperationCanceledException e) {
1708 if (fRestoreJobCanceledExplicitly) {
1709 showEmptyViewer();
1710 }
1711 return Status.CANCEL_STATUS;
1712 }
1713 return Status.OK_STATUS;
1714 }
1715 };
1716 fRestoreStateJob.schedule();
1717 }
1718 }
1719 }
1720
1721
1722 private void doRestoreInBackground(final IMemento memento, final IJavaElement[] hierarchyInput, IProgressMonitor monitor) throws JavaModelException {
1723 fHierarchyLifeCycle.doHierarchyRefresh(hierarchyInput, monitor);
1724 final boolean doRestore= !monitor.isCanceled();
1725 if (doRestore) {
1726 Display.getDefault().asyncExec(new Runnable() {
1727 public void run() {
1728 // running async: check first if view still exists
1729 if (fPagebook != null && !fPagebook.isDisposed()) {
1730 doRestoreState(memento, hierarchyInput);
1731 }
1732 }
1733 });
1734 }
1735 }
1736
1737
1738 final void doRestoreState(IMemento memento, IJavaElement input) {
1739 doRestoreState(memento, input == null ? null : new IJavaElement[] { input });
1740 }
1741
1742 /**
1743 * Restores the state of the type hierarchy view from the memento.
1744 *
1745 * @param memento the memento
1746 * @param input the input java elements
1747 * @since 3.7
1748 */
1749 final void doRestoreState(IMemento memento, IJavaElement[] input) {
1750 synchronized (this) {
1751 if (fRestoreStateJob == null) {
1752 return;
1753 }
1754 fRestoreStateJob= null;
1755 }
1756
1757 fWorkingSetActionGroup.restoreState(memento);
1758 setKeepShowingEmptyViewers(false);
1759 setInputElements(input);
1760
1761 Integer viewerIndex= memento.getInteger(TAG_VIEW);
1762 if (viewerIndex != null) {
1763 setHierarchyMode(viewerIndex.intValue());
1764 }
1765 Integer layout= memento.getInteger(TAG_LAYOUT);
1766 if (layout != null) {
1767 setViewLayout(layout.intValue());
1768 }
1769
1770 Integer val= memento.getInteger(TAG_EDITOR_LINKING);
1771 if (val != null) {
1772 setLinkingEnabled(val.intValue() != 0);
1773 }
1774
1775 Integer showQualified= memento.getInteger(TAG_QUALIFIED_NAMES);
1776 if (showQualified != null) {
1777 showQualifiedTypeNames(showQualified.intValue() != 0);
1778 }
1779
1780 updateCheckedState();
1781
1782 Integer ratio= memento.getInteger(TAG_RATIO);
1783 if (ratio != null) {
1784 fTypeMethodsSplitter.setWeights(new int[] { ratio.intValue(), 1000 - ratio.intValue() });
1785 }
1786 ScrollBar bar= getCurrentViewer().getTree().getVerticalBar();
1787 if (bar != null) {
1788 Integer vScroll= memento.getInteger(TAG_VERTICAL_SCROLL);
1789 if (vScroll != null) {
1790 bar.setSelection(vScroll.intValue());
1791 }
1792 }
1793 fMethodsViewer.restoreState(memento);
1794 }
1795
1796 /**
1797 * View part becomes visible.
1798 *
1799 * @param isVisible <code>true</code> if visible
1800 */
1801 protected void visibilityChanged(boolean isVisible) {
1802 fIsVisible= isVisible;
1803 if (isVisible && fNeedRefresh) {
1804 doTypeHierarchyChangedOnViewers(null);
1805 }
1806 fNeedRefresh= false;
1807 }
1808
1809
1810 /**
1811 * Link selection to active editor.
1812 * @param editor The activated editor
1813 */
1814 protected void editorActivated(IEditorPart editor) {
1815 if (!isLinkingEnabled()) {
1816 return;
1817 }
1818 if (fInputElements == null) {
1819 // no type hierarchy shown
1820 return;
1821 }
1822
1823 IJavaElement elem= (IJavaElement)editor.getEditorInput().getAdapter(IJavaElement.class);
1824 if (elem instanceof ITypeRoot) {
1825 IType type= ((ITypeRoot) elem).findPrimaryType();
1826 if (type != null) {
1827 internalSelectType(type, true);
1828 if (getCurrentViewer().getSelection().isEmpty()) {
1829 updateMethodViewer(null);
1830 } else {
1831 updateMethodViewer(type);
1832 }
1833 }
1834 }
1835 }
1836
1837 /* (non-Javadoc)
1838 * @see org.eclipse.jdt.internal.ui.viewsupport.IViewPartInputProvider#getViewPartInput()
1839 */
1840 public Object getViewPartInput() {
1841 return fInputElements;
1842 }
1843
1844
1845 /**
1846 * @return Returns the <code>IShowInSource</code> for this view.
1847 */
1848 protected IShowInSource getShowInSource() {
1849 return new IShowInSource() {
1850 public ShowInContext getShowInContext() {
1851 return new ShowInContext(
1852 null,
1853 getSite().getSelectionProvider().getSelection());
1854 }
1855 };
1856 }
1857
1858 /* (non-Javadoc)
1859 * @see org.eclipse.jdt.ui.ITypeHierarchyViewPart#isLinkingEnabled()
1860 */
1861 public boolean isLinkingEnabled() {
1862 return fLinkingEnabled;
1863 }
1864
1865 /* (non-Javadoc)
1866 * @see org.eclipse.jdt.ui.ITypeHierarchyViewPart#setLinkingEnabled(boolean)
1867 */
1868 public void setLinkingEnabled(boolean enabled) {
1869 fLinkingEnabled= enabled;
1870 fToggleLinkingAction.setChecked(enabled);
1871 fDialogSettings.put(DIALOGSTORE_LINKEDITORS, enabled);
1872
1873 if (enabled) {
1874 IWorkbenchPartSite site= getSite();
1875 if (site != null) {
1876 IEditorPart editor = site.getPage().getActiveEditor();
1877 if (editor != null) {
1878 editorActivated(editor);
1879 }
1880 }
1881 }
1882 }
1883
1884 public void clearNeededRefresh() {
1885 fNeedRefresh= false;
1886 }
1887
1888 /**
1889 * Sets the empty viewer when the user cancels the computation.
1890 *
1891 * @since 3.6
1892 */
1893 public void showEmptyViewer() {
1894 Display.getDefault().asyncExec(new Runnable() {
1895 public void run() {
1896 if (isDisposed())
1897 return;
1898
1899 clearInput();
1900 setKeepShowingEmptyViewers(true);
1901 }
1902 });
1903 }
1904
1905 /**
1906 * Checks if the type hierarchy view part has been disposed.
1907 *
1908 * @return <code>true</code> if the type hierarchy view part has been disposed, <code>false</code> otherwise
1909 * @since 3.6
1910 */
1911 private boolean isDisposed() {
1912 return fHierarchyLifeCycle == null;
1913 }
1914
1915 /**
1916 * Returns the type hierarchy life cycle.
1917 *
1918 * @return the type hierarchy life cycle
1919 *
1920 * @since 3.6
1921 */
1922 public TypeHierarchyLifeCycle getTypeHierarchyLifeCycle() {
1923 return fHierarchyLifeCycle;
1924
1925 }
1926
1927 /**
1928 * Sets the input for all the hierarchy viewers with their respective viewer instances.
1929 *
1930 * @since 3.6
1931 */
1932 public void setViewersInput() {
1933 for (int i= 0; i < fAllViewers.length; i++) {
1934 fAllViewers[i].setInput(fAllViewers[i]);
1935 }
1936 setKeepShowingEmptyViewers(false);
1937 }
1938
1939 /**
1940 * Sets whether empty viewers should keep showing. If false, replace with fEmptyTypesViewer.
1941 *
1942 * @param keepShowingEmptyViewers <code>true</code> if the empty viewers can be shown,
1943 * <code>false otherwise
1944 *
1945 * @since 3.6
1946 */
1947 public void setKeepShowingEmptyViewers(boolean keepShowingEmptyViewers) {
1948 fKeepShowingEmptyViewers= keepShowingEmptyViewers;
1949 }
1950
1951 /**
1952 * Returns value that determines whether the empty viewers should keep showing. If false,
1953 * replace with fEmptyTypesViewer.
1954 *
1955 * @return <code>true</code> if the empty viewers can be shown, <code>false otherwise
1956 *
1957 * @since 3.6
1958 */
1959 public boolean isKeepShowingEmptyViewers() {
1960 return fKeepShowingEmptyViewers;
1961 }
1962}