package com.redhat.ceylon.eclipse.code.editor;
import org.eclipse.jface.text.source.projection.ProjectionViewer;
import org.eclipse.ui.IPartListener2;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.IWorkbenchPartSite;
/**
* Runner that will toggle folding either instantly (if the editor is
* visible) or the next time it becomes visible. If a runner is started when
* there is already one registered, the registered one is canceled as
* toggling folding twice is a no-op.
* <p>
* The access to the fFoldingRunner field is not thread-safe, it is assumed
* that <code>runWhenNextVisible</code> is only called from the UI thread.
* </p>
*
* @since 3.1
*/
final class ToggleFoldingRunner implements IPartListener2 {
/**
*
*/
private final CeylonEditor editor;
/**
* @param ceylonEditor
*/
ToggleFoldingRunner(CeylonEditor ceylonEditor) {
editor = ceylonEditor;
}
/**
* The workbench page we registered the part listener with, or
* <code>null</code>.
*/
private IWorkbenchPage fPage;
/**
* Does the actual toggling of projection.
*/
private void toggleFolding() {
ProjectionViewer pv= editor.getCeylonSourceViewer();
if (pv.isProjectionMode() != editor.isFoldingEnabled()) {
if (pv.canDoOperation(ProjectionViewer.TOGGLE)) {
pv.doOperation(ProjectionViewer.TOGGLE);
}
}
}
/**
* Makes sure that the editor's folding state is correct the next time
* it becomes visible. If it already is visible, it toggles the folding
* state. If not, it either registers a part listener to toggle folding
* when the editor becomes visible, or cancels an already registered
* runner.
*/
public void runWhenNextVisible() {
// if there is one already: toggling twice is the identity
if (editor.fFoldingRunner != null) {
editor.fFoldingRunner.cancel();
return;
}
IWorkbenchPartSite site= editor.getSite();
if (site != null) {
IWorkbenchPage page= site.getPage();
if (!page.isPartVisible(editor)) {
// if we're not visible - defer until visible
fPage= page;
editor.fFoldingRunner= this;
page.addPartListener(this);
return;
}
}
// we're visible - run now
toggleFolding();
}
/**
* Remove the listener and clear the field.
*/
private void cancel() {
if (fPage != null) {
fPage.removePartListener(this);
fPage= null;
}
if (editor.fFoldingRunner == this)
editor.fFoldingRunner= null;
}
/*
* @see org.eclipse.ui.IPartListener2#partVisible(org.eclipse.ui.IWorkbenchPartReference)
*/
public void partVisible(IWorkbenchPartReference partRef) {
if (editor.equals(partRef.getPart(false))) {
cancel();
toggleFolding();
}
}
/*
* @see org.eclipse.ui.IPartListener2#partClosed(org.eclipse.ui.IWorkbenchPartReference)
*/
public void partClosed(IWorkbenchPartReference partRef) {
if (editor.equals(partRef.getPart(false))) {
cancel();
}
}
public void partActivated(IWorkbenchPartReference partRef) {}
public void partBroughtToTop(IWorkbenchPartReference partRef) {}
public void partDeactivated(IWorkbenchPartReference partRef) {}
public void partOpened(IWorkbenchPartReference partRef) {}
public void partHidden(IWorkbenchPartReference partRef) {}
public void partInputChanged(IWorkbenchPartReference partRef) {}
}