blob: c88dc7aa505f4588d4a82346d39e036dffeffe54 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2015 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.ui.internal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import org.eclipse.core.runtime.Assert;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.INavigationHistory;
import org.eclipse.ui.INavigationLocation;
import org.eclipse.ui.INavigationLocationProvider;
import org.eclipse.ui.IPartListener2;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.internal.StartupThreading.StartupRunnable;
/**
* Implementation of the back and forward actions.
*/
public class NavigationHistory implements INavigationHistory {
private static final boolean DEBUG = false;
private static final int CAPACITY = 50;
private NavigationHistoryAction backwardAction;
private NavigationHistoryAction forwardAction;
private int ignoreEntries;
private ArrayList<NavigationHistoryEntry> history = new ArrayList<>(CAPACITY);
Map<Object, PerTabHistory> perTabHistoryMap = new HashMap<>();
private ArrayList<NavigationHistoryEditorInfo> editors = new ArrayList<>(CAPACITY);
private IWorkbenchPage page;
private int activeEntry = 0;
/**
* Creates a new NavigationHistory to keep the NavigationLocation entries of the
* specified page.
*
* @param page the workbench page
*/
public NavigationHistory(final IWorkbenchPage page) {
this.page = page;
page.addPartListener(new IPartListener2() {
@Override
public void partActivated(IWorkbenchPartReference partRef) {
}
@Override
public void partBroughtToTop(IWorkbenchPartReference partRef) {
}
@Override
public void partDeactivated(IWorkbenchPartReference partRef) {
}
@Override
public void partOpened(IWorkbenchPartReference partRef) {
}
@Override
public void partHidden(IWorkbenchPartReference partRef) {
}
@Override
public void partVisible(IWorkbenchPartReference partRef) {
}
@Override
public void partClosed(IWorkbenchPartReference partRef) {
if (isPerTabHistoryEnabled() && partRef instanceof EditorReference) {
if (!((EditorReference) partRef).isDisposed()) {
Object editorTabCookie = ((EditorReference) partRef).getModel().getWidget();
disposeHistoryForTab(editorTabCookie);
updateActions();
}
}
updateNavigationHistory(partRef, true);
}
@Override
public void partInputChanged(IWorkbenchPartReference partRef) {
updateNavigationHistory(partRef, false);
}
private void updateNavigationHistory(IWorkbenchPartReference partRef, boolean partClosed) {
if (partRef != null && partRef.getPart(false) instanceof IEditorPart) {
IEditorPart editor = (IEditorPart) partRef.getPart(false);
IEditorInput input = editor.getEditorInput();
String id = editor.getSite().getId();
Iterator<NavigationHistoryEditorInfo> e = editors.iterator();
NavigationHistoryEditorInfo info = null;
NavigationHistoryEditorInfo currentInfo = null;
NavigationHistoryEntry current = getEntry(activeEntry);
if (current != null) {
currentInfo = current.editorInfo;
}
while (e.hasNext()) {
info = e.next();
if (id.equals(info.editorID) && input.equals(info.editorInput)) {
if (partClosed && info != currentInfo) {
info.handlePartClosed();
}
break;
}
info = null;
}
if (info == null) {
return;
}
boolean isEntryDisposed = false;
Iterator<NavigationHistoryEntry> it = history.iterator();
int i = 0;
while (it.hasNext()) {
NavigationHistoryEntry entry = it.next();
if (entry.editorInfo == info) {
if (!entry.handlePartClosed()) {
// update the active entry since we are removing an item
if (i < activeEntry) {
activeEntry--;
} else if (i == activeEntry) {
if (i != 0) {
activeEntry--;
}
} else {
// activeEntry is before item we deleted
i++;
}
isEntryDisposed = true;
it.remove();
disposeEntry(entry);
} else {
i++;
}
}
}
/*
* Promote the entry of the last closed editor to be the active one, see:
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=154431
*/
if (!isEntryDisposed && page.getActiveEditor() == null && activeEntry < history.size())
activeEntry++;
updateActions();
}
}
});
}
private Display getDisplay() {
return Workbench.getInstance().getDisplay();
}
private boolean isPerTabHistoryEnabled() {
return false;
}
/*
* Adds an editor to the editor history without getting its location.
*/
public void markEditor(final IEditorPart part) {
if (ignoreEntries > 0 || part == null) {
return;
}
/*
* Ignore all entries until the async exec runs. Workaround to avoid extra entry
* when using Open Declaration (F3) that opens another editor.
*/
ignoreEntries++;
getDisplay().asyncExec(() -> {
if (--ignoreEntries == 0) {
if (part.getEditorSite() instanceof EditorSite) {
EditorSite site = (EditorSite) part.getEditorSite();
Control c = (Control) site.getModel().getWidget();
if (c == null || c.isDisposed()) {
return;
}
NavigationHistoryEntry e = getEntry(activeEntry);
if (e != null && part.getEditorInput() != e.editorInfo.editorInput) {
updateEntry(e);
}
addEntry(part);
}
}
});
}
@Override
public void markLocation(IEditorPart part) {
addEntry(part);
}
/*
* Return the backward history entries. Return in restore order (i.e., the first
* entry is the entry that would become active if the "Backward" action was
* executed). <p> (Called by NavigationHistoryAction) </p>
*/
NavigationHistoryEntry[] getBackwardEntries() {
if (isPerTabHistoryEnabled()) {
return getEntriesForTab(false);
}
int length = activeEntry;
NavigationHistoryEntry[] entries = new NavigationHistoryEntry[length];
for (int i = 0; i < activeEntry; i++) {
entries[activeEntry - 1 - i] = getEntry(i);
}
return entries;
}
/*
* Return the forward history entries. Return in restore order (i.e., the first
* entry is the entry that would become active if the "Forward" action was
* executed). <p> (Called by NavigationHistoryAction) </p>
*/
NavigationHistoryEntry[] getForwardEntries() {
if (isPerTabHistoryEnabled()) {
return getEntriesForTab(true);
}
int length = history.size() - activeEntry - 1;
length = Math.max(0, length);
NavigationHistoryEntry[] entries = new NavigationHistoryEntry[length];
for (int i = activeEntry + 1; i < history.size(); i++) {
entries[i - activeEntry - 1] = getEntry(i);
}
return entries;
}
@Override
public INavigationLocation[] getLocations() {
INavigationLocation result[] = new INavigationLocation[history.size()];
for (int i = 0; i < result.length; i++) {
NavigationHistoryEntry e = history.get(i);
result[i] = e.location;
}
return result;
}
@Override
public INavigationLocation getCurrentLocation() {
NavigationHistoryEntry entry = getEntry(activeEntry);
return entry == null ? null : entry.location;
}
/**
* Disposes this NavigationHistory and all entries.
*/
public void dispose() {
disposeHistoryForTabs();
Iterator<NavigationHistoryEntry> e = history.iterator();
while (e.hasNext()) {
NavigationHistoryEntry entry = e.next();
disposeEntry(entry);
}
}
/**
* Keeps a reference to the forward action to update its state whenever needed.
* <p>
* (Called by NavigationHistoryAction)
* </p>
*/
void setForwardAction(NavigationHistoryAction action) {
forwardAction = action;
updateActions();
}
/**
* Keeps a reference to the backward action to update its state whenever needed.
* <p>
* (Called by NavigationHistoryAction)
* </p>
*/
void setBackwardAction(NavigationHistoryAction action) {
backwardAction = action;
updateActions();
}
/*
* Returns the history entry indexed by <code>index</code>
*/
private NavigationHistoryEntry getEntry(int index) {
if (0 <= index && index < history.size()) {
return history.get(index);
}
return null;
}
/*
* Adds the specified entry to the history.
*/
private void add(NavigationHistoryEntry entry) {
removeForwardEntries();
if (history.size() == CAPACITY) {
NavigationHistoryEntry e = history.remove(0);
disposeEntry(e);
}
history.add(entry);
activeEntry = history.size() - 1;
}
/*
* Remove all entries after the active entry.
*/
private void removeForwardEntries() {
int length = history.size();
for (int i = activeEntry + 1; i < length; i++) {
NavigationHistoryEntry e = history.remove(activeEntry + 1);
disposeEntry(e);
}
}
/*
* Adds a location to the history.
*/
private void addEntry(IEditorPart part) {
if (ignoreEntries > 0 || part == null) {
return;
}
if (isPerTabHistoryEnabled()) {
markLocationForTab(part);
}
INavigationLocation location = null;
if (part instanceof INavigationLocationProvider) {
location = ((INavigationLocationProvider) part).createNavigationLocation();
}
NavigationHistoryEntry current = getEntry(activeEntry);
if (current != null && current.editorInfo.memento != null) {
current.editorInfo.restoreEditor();
checkDuplicates(current.editorInfo);
}
NavigationHistoryEntry e = createEntry(page, part, location);
if (current == null) {
add(e);
} else {
if (e.mergeInto(current)) {
disposeEntry(e);
removeForwardEntries();
} else {
add(e);
}
}
printEntries("added entry"); //$NON-NLS-1$
updateActions();
}
/*
* Prints all the entries in the console. For debug only.
*/
private void printEntries(String label) {
if (DEBUG) {
System.out.println("+++++ " + label + "+++++ "); //$NON-NLS-1$ //$NON-NLS-2$
int size = history.size();
for (int i = 0; i < size; i++) {
String append = activeEntry == i ? ">>" : ""; //$NON-NLS-1$ //$NON-NLS-2$
System.out.println(append + "Index: " + i + " " + history.get(i)); //$NON-NLS-1$ //$NON-NLS-2$
}
}
}
/*
* Returns true if the forward action can be performed otherwise returns false.
* <p> (Called by NavigationHistoryAction) </p>
*/
/* package */boolean canForward() {
if (isPerTabHistoryEnabled()) {
return hasEntriesForTab(true);
}
return (0 <= activeEntry + 1) && (activeEntry + 1 < history.size());
}
/*
* Returns true if the backward action can be performed otherwise returns false.
* <p> (Called by NavigationHistoryAction) </p>
*/
/* package */boolean canBackward() {
if (isPerTabHistoryEnabled()) {
return hasEntriesForTab(false);
}
return (0 <= activeEntry - 1) && (activeEntry - 1 < history.size());
}
/*
* Update the actions enable/disable and tooltip state.
*/
private void updateActions() {
if (backwardAction != null) {
backwardAction.update();
}
if (forwardAction != null) {
forwardAction.update();
}
}
/*
* Restore the specified entry
*/
private void gotoEntry(NavigationHistoryEntry entry) {
if (entry == null) {
return;
}
try {
ignoreEntries++;
if (entry.editorInfo.memento != null) {
entry.editorInfo.restoreEditor();
checkDuplicates(entry.editorInfo);
}
entry.restoreLocation();
updateActions();
printEntries("goto entry"); //$NON-NLS-1$
} finally {
ignoreEntries--;
}
}
/*
* update the active entry
*/
private void updateEntry(NavigationHistoryEntry activeEntry) {
if (activeEntry == null || activeEntry.location == null) {
return;
}
activeEntry.location.update();
printEntries("updateEntry"); //$NON-NLS-1$
}
/*
* Perform the forward action by getting the next location and restoring its
* context. <p> (Called by NavigationHistoryAction) </p>
*/
void forward() {
if (isPerTabHistoryEnabled()) {
forwardForTab();
return;
}
if (canForward()) {
shiftEntry(true);
}
}
/*
* Perform the backward action by getting the previous location and restoring
* its context. <p> (Called by NavigationHistoryAction) </p>
*/
void backward() {
if (isPerTabHistoryEnabled()) {
backwardForTab();
return;
}
if (canBackward()) {
shiftEntry(false);
}
}
/*
* Shift the history back or forward
*/
private void shiftEntry(boolean forward) {
updateEntry(getEntry(activeEntry));
if (forward) {
activeEntry++;
} else {
activeEntry--;
}
NavigationHistoryEntry entry = getEntry(activeEntry);
if (entry != null) {
gotoEntry(entry);
}
}
/*
* Shift the history to the given entry. <p> (Called by NavigationHistoryAction)
* </p>
*/
void shiftCurrentEntry(NavigationHistoryEntry entry, boolean forward) {
if (isPerTabHistoryEnabled()) {
gotoEntryForTab(entry, forward);
return;
}
updateEntry(getEntry(activeEntry));
activeEntry = history.indexOf(entry);
gotoEntry(entry);
}
/**
* Save the state of this history into the memento.
*/
void saveState(IMemento memento) {
NavigationHistoryEntry cEntry = getEntry(activeEntry);
if (cEntry == null || !cEntry.editorInfo.isPersistable()) {
return;
}
ArrayList<NavigationHistoryEditorInfo> editors = new ArrayList<>(this.editors);
for (Iterator<NavigationHistoryEditorInfo> iter = editors.iterator(); iter.hasNext();) {
NavigationHistoryEditorInfo info = iter.next();
if (!info.isPersistable()) {
iter.remove();
}
}
IMemento editorsMem = memento.createChild(IWorkbenchConstants.TAG_EDITORS);
for (NavigationHistoryEditorInfo info : editors) {
info.saveState(editorsMem.createChild(IWorkbenchConstants.TAG_EDITOR));
}
ArrayList<NavigationHistoryEntry> list = new ArrayList<>(history.size());
int size = history.size();
for (int i = 0; i < size; i++) {
NavigationHistoryEntry entry = history.get(i);
if (entry.editorInfo.isPersistable()) {
list.add(entry);
}
}
size = list.size();
for (int i = 0; i < size; i++) {
NavigationHistoryEntry entry = list.get(i);
IMemento childMem = memento.createChild(IWorkbenchConstants.TAG_ITEM);
if (entry == cEntry) {
childMem.putString(IWorkbenchConstants.TAG_ACTIVE, "true"); //$NON-NLS-1$
}
entry.saveState(childMem, list);
childMem.putInteger(IWorkbenchConstants.TAG_INDEX, editors.indexOf(entry.editorInfo));
}
}
/**
* Restore the state of this history from the memento.
*/
void restoreState(IMemento memento) {
IMemento editorsMem = memento.getChild(IWorkbenchConstants.TAG_EDITORS);
IMemento items[] = memento.getChildren(IWorkbenchConstants.TAG_ITEM);
if (items.length == 0 || editorsMem == null) {
if (page.getActiveEditor() != null) {
markLocation(page.getActiveEditor());
}
return;
}
IMemento children[] = editorsMem.getChildren(IWorkbenchConstants.TAG_EDITOR);
NavigationHistoryEditorInfo editorsInfo[] = new NavigationHistoryEditorInfo[children.length];
for (int i = 0; i < editorsInfo.length; i++) {
editorsInfo[i] = new NavigationHistoryEditorInfo(children[i]);
editors.add(editorsInfo[i]);
}
for (int i = 0; i < items.length; i++) {
IMemento item = items[i];
int index = item.getInteger(IWorkbenchConstants.TAG_INDEX).intValue();
NavigationHistoryEditorInfo info = editorsInfo[index];
info.refCount++;
NavigationHistoryEntry entry = new NavigationHistoryEntry(info, page, null, null);
history.add(entry);
entry.restoreState(item);
if (item.getString(IWorkbenchConstants.TAG_ACTIVE) != null) {
activeEntry = i;
}
}
final NavigationHistoryEntry entry = getEntry(activeEntry);
if (entry != null && entry.editorInfo.editorInput != null) {
if (page.getActiveEditor() == page.findEditor(entry.editorInfo.editorInput)) {
StartupThreading.runWithoutExceptions(new StartupRunnable() {
@Override
public void runWithException() throws Throwable {
gotoEntry(entry);
}
});
}
}
}
public NavigationHistoryEntry createEntry(IWorkbenchPage page, IEditorPart part, INavigationLocation location) {
String editorID = part.getSite().getId();
IEditorInput editorInput = part.getEditorInput();
NavigationHistoryEditorInfo info = null;
for (Iterator<NavigationHistoryEditorInfo> iter = editors.iterator(); iter.hasNext();) {
info = iter.next();
if (editorID.equals(info.editorID) && editorInput.equals(info.editorInput)) {
info.refCount++;
break;
}
info = null;
}
if (info == null) {
info = new NavigationHistoryEditorInfo(part);
info.refCount++;
editors.add(info);
}
return new NavigationHistoryEntry(info, page, part, location);
}
public void disposeEntry(NavigationHistoryEntry entry) {
if (entry.editorInfo == null) {
return;
}
entry.editorInfo.refCount--;
if (entry.editorInfo.refCount == 0) {
editors.remove(entry.editorInfo);
}
entry.dispose();
}
void checkDuplicates(NavigationHistoryEditorInfo info) {
NavigationHistoryEditorInfo dup = null;
if (info.editorInput == null) {
return;
}
for (Iterator<NavigationHistoryEditorInfo> iter = editors.iterator(); iter.hasNext();) {
dup = iter.next();
if (info != dup && info.editorID.equals(dup.editorID) && info.editorInput.equals(dup.editorInput)) {
break;
}
dup = null;
}
if (dup == null) {
return;
}
for (NavigationHistoryEntry entry : history) {
if (entry.editorInfo == dup) {
entry.editorInfo = info;
info.refCount++;
}
}
editors.remove(dup);
}
/*********************************************************/
/*** new per-tab history code ***/
/*********************************************************/
private static class PerTabHistory {
LinkedList<NavigationHistoryEntry> backwardEntries = new LinkedList<>();
NavigationHistoryEntry currentEntry = null;
LinkedList<NavigationHistoryEntry> forwardEntries = new LinkedList<>();
}
private void setNewCurrentEntryForTab(PerTabHistory perTabHistory, NavigationHistoryEntry entry) {
if (perTabHistory.currentEntry != null) {
perTabHistory.backwardEntries.addFirst(perTabHistory.currentEntry);
}
perTabHistory.currentEntry = entry;
removeEntriesForTab(perTabHistory.forwardEntries);
}
private Object getCookieForTab(IEditorPart part) {
if (part != null) {
IWorkbenchPartSite site = part.getSite();
if (site instanceof PartSite) {
PartSite partSite = (PartSite) site;
WorkbenchPartReference ref = (WorkbenchPartReference) partSite.getPartReference();
if (!ref.isDisposed()) {
return partSite.getModel().getWidget();
}
}
}
return null;
}
private void markLocationForTab(IEditorPart part) {
if (part instanceof ErrorEditorPart) {
updateActions();
return;
}
Object tabCookie = getCookieForTab(part);
if (tabCookie != null) {
INavigationLocation location = null;
if (part instanceof INavigationLocationProvider) {
location = ((INavigationLocationProvider) part).createNavigationLocation();
}
PerTabHistory perTabHistory = perTabHistoryMap.get(tabCookie);
if (perTabHistory == null) {
perTabHistory = new PerTabHistory();
perTabHistoryMap.put(tabCookie, perTabHistory);
}
NavigationHistoryEntry current = perTabHistory.currentEntry;
if (current != null && current.editorInfo.memento != null) {
current.editorInfo.restoreEditor();
checkDuplicates(current.editorInfo);
}
NavigationHistoryEntry entry = createEntry(page, part, location);
if (current != null && entry.mergeInto(current)) {
disposeEntry(entry);
removeEntriesForTab(perTabHistory.forwardEntries);
} else {
setNewCurrentEntryForTab(perTabHistory, entry);
}
}
updateActions();
}
public void updateCookieForTab(Object oldCookie, Object newCookie) {
if (newCookie.equals(oldCookie)) {
return;
}
PerTabHistory perTabHistory = perTabHistoryMap.remove(oldCookie);
if (perTabHistory != null) {
perTabHistoryMap.put(newCookie, perTabHistory);
}
}
private void gotoEntryForTab(NavigationHistoryEntry target, boolean forward) {
Object editorTabCookie = getCookieForTab(page.getActiveEditor());
if (editorTabCookie != null) {
PerTabHistory perTabHistory = perTabHistoryMap.get(editorTabCookie);
if (perTabHistory != null) {
LinkedList<NavigationHistoryEntry> source = forward ? perTabHistory.forwardEntries
: perTabHistory.backwardEntries;
LinkedList<NavigationHistoryEntry> destination = forward ? perTabHistory.backwardEntries
: perTabHistory.forwardEntries;
if (perTabHistory.currentEntry != null) {
if (perTabHistory.currentEntry.location != null) {
perTabHistory.currentEntry.location.update();
}
destination.addFirst(perTabHistory.currentEntry);
}
NavigationHistoryEntry newCurrent = null;
while (!source.isEmpty() && newCurrent == null) {
NavigationHistoryEntry entry = source.removeFirst();
if (entry.equals(target)) {
newCurrent = entry;
} else {
destination.addFirst(entry);
}
}
Assert.isTrue(newCurrent != null);
perTabHistory.currentEntry = newCurrent;
try {
ignoreEntries++;
if (newCurrent.editorInfo.memento != null) {
newCurrent.editorInfo.restoreEditor();
checkDuplicates(newCurrent.editorInfo);
}
newCurrent.restoreLocation();
updateActions();
} finally {
ignoreEntries--;
}
}
}
}
private void forwardForTab() {
Object editorTabCookie = getCookieForTab(page.getActiveEditor());
if (editorTabCookie != null) {
PerTabHistory perTabHistory = perTabHistoryMap.get(editorTabCookie);
if (perTabHistory != null && !perTabHistory.forwardEntries.isEmpty()) {
NavigationHistoryEntry newCurrent = perTabHistory.forwardEntries.removeFirst();
if (perTabHistory.currentEntry != null) {
final INavigationLocation location = perTabHistory.currentEntry.location;
if (location != null) {
location.update();
}
perTabHistory.backwardEntries.addFirst(perTabHistory.currentEntry);
}
perTabHistory.currentEntry = newCurrent;
try {
ignoreEntries++;
if (newCurrent.editorInfo.memento != null) {
newCurrent.editorInfo.restoreEditor();
checkDuplicates(newCurrent.editorInfo);
}
newCurrent.restoreLocation();
updateActions();
} finally {
ignoreEntries--;
}
}
}
}
private void backwardForTab() {
Object editorTabCookie = getCookieForTab(page.getActiveEditor());
if (editorTabCookie != null) {
PerTabHistory perTabHistory = perTabHistoryMap.get(editorTabCookie);
if (perTabHistory != null && !perTabHistory.backwardEntries.isEmpty()) {
NavigationHistoryEntry newCurrent = perTabHistory.backwardEntries
.removeFirst();
if (perTabHistory.currentEntry != null) {
perTabHistory.currentEntry.location.update();
perTabHistory.forwardEntries.addFirst(perTabHistory.currentEntry);
}
perTabHistory.currentEntry = newCurrent;
try {
ignoreEntries++;
if (newCurrent.editorInfo.memento != null) {
newCurrent.editorInfo.restoreEditor();
checkDuplicates(newCurrent.editorInfo);
}
newCurrent.restoreLocation();
updateActions();
} finally {
ignoreEntries--;
}
}
}
}
private boolean hasEntriesForTab(boolean forward) {
Object editorTabCookie = getCookieForTab(page.getActiveEditor());
if (editorTabCookie != null) {
PerTabHistory perTabHistory = perTabHistoryMap.get(editorTabCookie);
if (perTabHistory != null) {
LinkedList<NavigationHistoryEntry> entries = forward ? perTabHistory.forwardEntries
: perTabHistory.backwardEntries;
return !entries.isEmpty();
}
}
return false;
}
/**
* Returns entries in restore order.
*
* @param forward <code>true</code> for forward and <code>false</code> for
* backward history
* @return the navigation history entries
*/
private NavigationHistoryEntry[] getEntriesForTab(boolean forward) {
Object editorTabCookie = getCookieForTab(page.getActiveEditor());
if (editorTabCookie != null) {
PerTabHistory perTabHistory = perTabHistoryMap.get(editorTabCookie);
if (perTabHistory != null) {
LinkedList<NavigationHistoryEntry> entries = forward ? perTabHistory.forwardEntries
: perTabHistory.backwardEntries;
return entries.toArray(new NavigationHistoryEntry[entries.size()]);
}
}
return new NavigationHistoryEntry[0];
}
private void disposeHistoryForTabs() {
Object[] keys = perTabHistoryMap.keySet().toArray();
for (Object key : keys) {
disposeHistoryForTab(key);
}
}
void disposeHistoryForTab(Object editorTabCookie) {
PerTabHistory perTabHistory = perTabHistoryMap.remove(editorTabCookie);
if (perTabHistory != null) {
if (perTabHistory.currentEntry != null) {
disposeEntry(perTabHistory.currentEntry);
perTabHistory.currentEntry = null;
}
removeEntriesForTab(perTabHistory.backwardEntries);
removeEntriesForTab(perTabHistory.forwardEntries);
}
}
private void removeEntriesForTab(LinkedList<NavigationHistoryEntry> entries) {
for (Iterator<NavigationHistoryEntry> it = entries.iterator(); it.hasNext();) {
NavigationHistoryEntry entry = it.next();
disposeEntry(entry);
it.remove();
}
}
public boolean updateActive(IEditorPart editor) {
NavigationHistoryEntry e = getEntry(activeEntry);
if (e == null)
return false;
// 1) check if editor ID matches
IWorkbenchPartSite site = editor.getSite();
if (site == null) // might happen if site has not being initialized yet
return false;
String editorID = site.getId();
if (editorID == null) // should not happen for an editor
return false;
if (!editorID.equals(e.editorInfo.editorID))
return false;
// 2) check that input matches
IEditorInput input = editor.getEditorInput();
if (input == null)
return false;
if (!input.equals(e.editorInfo.editorInput))
return false;
updateEntry(e);
return true;
}
}