Merge branch 'master' of git.labs.intellij.net:idea/community

This commit is contained in:
Dmitry Avdeev
2009-12-03 16:21:28 +03:00
6 changed files with 131 additions and 68 deletions
@@ -16,15 +16,16 @@
package com.intellij.ide.structureView.impl;
import com.intellij.openapi.wm.ToolWindowFactory;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.project.Project;
import com.intellij.ide.structureView.StructureViewFactory;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowFactory;
/**
* @author yole
*/
public class StructureViewToolWindowFactory implements ToolWindowFactory {
public class StructureViewToolWindowFactory implements ToolWindowFactory, DumbAware {
public void createToolWindowContent(Project project, ToolWindow toolWindow) {
StructureViewFactoryImpl factory = (StructureViewFactoryImpl)StructureViewFactory.getInstance(project);
factory.initToolWindow(toolWindow);
@@ -21,8 +21,9 @@ import com.intellij.ide.util.treeView.smartTree.TreeAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.actionSystem.ToggleAction;
import com.intellij.openapi.project.DumbAware;
public class TreeActionWrapper extends ToggleAction{
public class TreeActionWrapper extends ToggleAction implements DumbAware {
private final TreeAction myAction;
private final TreeActionsOwner myStructureView;
@@ -258,7 +258,7 @@ public class AbstractTreeBuilder implements Disposable {
}
public final boolean isDisposed() {
return getUi() == null || getUi().isReleased();
return getUi() == null || getUi().isReleaseRequested();
}
/**
@@ -386,7 +386,10 @@ public class AbstractTreeBuilder implements Disposable {
public void dispose() {
if (isDisposed()) return;
myUi.release();
myUi.requestRelease();
}
void releaseUi() {
myUi = null;
}
@@ -110,6 +110,7 @@ public class AbstractTreeUi {
private UpdaterTreeState myUpdaterState;
private AbstractTreeBuilder myBuilder;
private boolean myReleaseRequested;
private final Set<DefaultMutableTreeNode> myUpdatingChildren = new HashSet<DefaultMutableTreeNode>();
private long myJanitorPollPeriod = Time.SECOND * 10;
@@ -187,14 +188,14 @@ public class AbstractTreeUi {
public void showNotify() {
myShowing = true;
myWasEverShown = true;
if (!isReleased()) {
if (!isReleaseRequested()) {
activate(true);
}
}
public void hideNotify() {
myShowing = false;
if (!isReleased()) {
if (!validateReleaseRequested()) {
deactivate();
}
}
@@ -268,7 +269,7 @@ public class AbstractTreeUi {
protected void doCleanUp() {
Runnable cleanup = new Runnable() {
public void run() {
if (!isReleased()) {
if (!isReleaseRequested()) {
cleanUpNow();
}
}
@@ -323,10 +324,19 @@ public class AbstractTreeUi {
}
}
public void requestRelease() {
if (isReleaseRequested()) return;
public void release() {
if (isReleased()) return;
assertIsDispatchThread();
myReleaseRequested = true;
getUpdater().requestRelease();
maybeReady();
}
private void releaseNow() {
myTree.removeTreeExpansionListener(myExpansionListener);
myTree.removeTreeSelectionListener(mySelectionListener);
myTree.removeFocusListener(myFocusListener);
@@ -347,8 +357,8 @@ public class AbstractTreeUi {
myTree = null;
setUpdater(null);
myWorker = null;
//todo [kirillk] afraid to do so just in release day, to uncomment
// myTreeStructure = null;
myTreeStructure = null;
myBuilder.releaseUi();
myBuilder = null;
clearNodeActions();
@@ -358,6 +368,23 @@ public class AbstractTreeUi {
myYeildingDoneRunnables.clear();
}
public boolean isReleaseRequested() {
return myReleaseRequested;
}
public boolean validateReleaseRequested() {
if (isReleaseRequested()) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
maybeReady();
}
});
return true;
} else {
return false;
}
}
public boolean isReleased() {
return myBuilder == null;
}
@@ -366,9 +393,13 @@ public class AbstractTreeUi {
if (!myUnbuiltNodes.contains(node)) return;
if (isLoadedInBackground(getElementFor(node))) return;
getTreeStructure().commit();
addSubtreeToUpdate(node);
getUpdater().performUpdate();
if (!isReleaseRequested()) {
getTreeStructure().commit();
addSubtreeToUpdate(node);
getUpdater().performUpdate();
} else {
processNodeActionsIfReady(node);
}
}
public final AbstractTreeStructure getTreeStructure() {
@@ -710,7 +741,7 @@ public class AbstractTreeUi {
else {
UIUtil.invokeLaterIfNeeded(new Runnable() {
public void run() {
if (!isReleased()) {
if (!validateReleaseRequested()) {
result.setDone(_update(nodeDescriptor));
}
else {
@@ -1067,6 +1098,7 @@ public class AbstractTreeUi {
.doWhenDone(new Runnable() {
public void run() {
if (isDisposed(node)) {
removeFromUpdating(node);
return;
}
@@ -1106,10 +1138,17 @@ public class AbstractTreeUi {
}).doWhenProcessed(new Runnable() {
public void run() {
myWillBeExpaned.remove(node);
removeFromUpdating(node);
processNodeActionsIfReady(node);
}
});
}
});
}).doWhenRejected(new Runnable() {
public void run() {
removeFromUpdating(node);
processNodeActionsIfReady(node);
}
});
}
private boolean isDisposed(DefaultMutableTreeNode node) {
@@ -1343,9 +1382,17 @@ public class AbstractTreeUi {
else {
if (isToYieldUpdateFor(node)) {
pass.setCurrentNode(node);
yieldAndRun(new Runnable() {
boolean wasRun = yieldAndRun(new Runnable() {
public void run() {
if (pass.isExpired()) return;
if (validateReleaseRequested()) {
result.setRejected();
return;
}
if (pass.isExpired()) {
result.setRejected();
return;
}
if (isRerunNeeded(pass)) {
runDone(new Runnable() {
@@ -1362,6 +1409,9 @@ public class AbstractTreeUi {
}
}
}, pass);
if (!wasRun) {
result.setRejected();
}
}
else {
processRunnable.run().notify(result);
@@ -1371,25 +1421,22 @@ public class AbstractTreeUi {
return result;
}
private void yieldAndRun(final Runnable runnable, final TreeUpdatePass pass) {
private boolean yieldAndRun(final Runnable runnable, final TreeUpdatePass pass) {
if (validateReleaseRequested()) return false;
myYeildingPasses.add(pass);
myYeildingNow = true;
yield(new Runnable() {
public void run() {
if (isReleased()) {
return;
}
runOnYieldingDone(new Runnable() {
public void run() {
if (isReleased()) {
return;
}
executeYieldingRequest(runnable, pass);
}
});
}
});
return true;
}
public boolean isYeildingNow() {
@@ -1433,6 +1480,11 @@ public class AbstractTreeUi {
if (isReleased()) return;
if (isReady()) {
if (isReleaseRequested()) {
releaseNow();
return;
}
if (myTree.isShowing() || myUpdateIfInactive) {
myInitialized.setDone();
}
@@ -1785,6 +1837,8 @@ public class AbstractTreeUi {
private boolean queueBackgroundUpdate(final UpdateInfo updateInfo, final DefaultMutableTreeNode node) {
assertIsDispatchThread();
if (validateReleaseRequested()) return false;
final Object oldElementFromDescriptor = getElementFromDescriptor(updateInfo.getDescriptor());
UpdateInfo loaded = getLoadedInBackground(oldElementFromDescriptor);
@@ -1804,10 +1858,6 @@ public class AbstractTreeUi {
final Ref<Object> elementFromDescriptor = new Ref<Object>();
Runnable buildRunnable = new Runnable() {
public void run() {
if (isReleased()) {
return;
}
if (!updateInfo.isDescriptorIsUpToDate()) {
update(updateInfo.getDescriptor(), true);
}
@@ -1834,7 +1884,6 @@ public class AbstractTreeUi {
final DefaultMutableTreeNode[] nodeToProcessActions = new DefaultMutableTreeNode[1];
Runnable updateRunnable = new Runnable() {
public void run() {
if (isReleased()) return;
if (children.get() == null) return;
if (isRerunNeeded(updateInfo.getPass())) {
@@ -2418,37 +2467,27 @@ public class AbstractTreeUi {
protected void queueToBackground(@NotNull final Runnable bgBuildAction,
@Nullable final Runnable edtPostRunnable,
@Nullable final Runnable finalizeEdtRunnable) {
if (validateReleaseRequested()) return;
registerWorkerTask(bgBuildAction);
final Runnable pooledThreadWithProgressRunnable = new Runnable() {
public void run() {
if (isReleased()) {
return;
}
final AbstractTreeBuilder builder = getBuilder();
builder.runBackgroundLoading(new Runnable() {
public void run() {
assertNotDispatchThread();
if (isReleased()) {
return;
}
try {
bgBuildAction.run();
if (edtPostRunnable != null && !isReleased()) {
if (edtPostRunnable != null) {
builder.updateAfterLoadedInBackground(new Runnable() {
public void run() {
try {
assertIsDispatchThread();
if (isReleased()) {
return;
}
edtPostRunnable.run();
}
finally {
@@ -2475,8 +2514,6 @@ public class AbstractTreeUi {
Runnable pooledThreadRunnable = new Runnable() {
public void run() {
if (isReleased()) return;
try {
if (myProgress != null) {
ProgressManager.getInstance().runProcess(pooledThreadWithProgressRunnable, myProgress);
@@ -2690,8 +2727,12 @@ public class AbstractTreeUi {
return false;
}
getUpdater().runAfterUpdate(runAfterUpdate);
getUpdater().addSubtreeToUpdate(root);
if (isReleaseRequested()) {
processNodeActionsIfReady(root);
} else {
getUpdater().runAfterUpdate(runAfterUpdate);
getUpdater().addSubtreeToUpdate(root);
}
return true;
}
@@ -3040,6 +3081,10 @@ public class AbstractTreeUi {
public void run() {
runDone(onDone);
}
}).doWhenRejected(new Runnable() {
public void run() {
runDone(onDone);
}
});
expandNext(element, 0, parentsOnly, checkIfInStructure, canSmartExpand, done);
@@ -3078,7 +3123,6 @@ public class AbstractTreeUi {
}
private void runDone(@Nullable Runnable done) {
if (isReleased()) return;
if (done == null) return;
if (isYeildingNow()) {
@@ -3171,7 +3215,6 @@ public class AbstractTreeUi {
addNodeAction(element, new NodeAction() {
public void onReady(final DefaultMutableTreeNode node) {
if (node.getChildCount() > 0 && !myTree.isExpanded(new TreePath(node.getPath()))) {
if (!isAutoExpand(node)) {
expand(node, canSmartExpand);
@@ -3254,6 +3297,8 @@ public class AbstractTreeUi {
}
public final boolean isNodeBeingBuilt(Object node) {
if (isReleaseRequested()) return false;
return getParentBuiltNode(node) != null;
}
@@ -3456,7 +3501,7 @@ public class AbstractTreeUi {
private void cleanUpNow() {
if (isReleased()) return;
if (isReleaseRequested()) return;
final UpdaterTreeState state = new UpdaterTreeState(this);
@@ -46,6 +46,7 @@ public class AbstractTreeUpdater implements Disposable, Activatable {
private final MergingUpdateQueue myUpdateQueue;
private long myUpdateCount;
private boolean myReleaseRequested;
public AbstractTreeUpdater(AbstractTreeBuilder treeBuilder) {
myTreeBuilder = treeBuilder;
@@ -96,13 +97,10 @@ public class AbstractTreeUpdater implements Disposable, Activatable {
}
public synchronized void addSubtreeToUpdate(@NotNull TreeUpdatePass toAdd) {
if (LOG.isDebugEnabled()) {
LOG.debug("addSubtreeToUpdate:" + toAdd.getNode());
}
if (myReleaseRequested) return;
assert !toAdd.isExpired();
final AbstractTreeUi ui = myTreeBuilder.getUi();
if (ui.isUpdatingNow(toAdd.getNode())) {
@@ -363,4 +361,12 @@ public class AbstractTreeUpdater implements Disposable, Activatable {
}
});
}
public void requestRelease() {
myReleaseRequested = true;
myNodeQueue.clear();
myUpdateQueue.cancelAllUpdates();
myUpdateQueue.deactivate();
}
}
@@ -19,6 +19,7 @@ package com.intellij.ui;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.ToggleAction;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.IconLoader;
@@ -42,16 +43,22 @@ public abstract class AutoScrollFromSourceHandler implements Disposable {
public abstract void install();
public ToggleAction createToggleAction() {
return new ToggleAction(UIBundle.message("autoscroll.from.source.action.name"),
UIBundle.message("autoscroll.from.source.action.description"), IconLoader.getIcon("/general/autoscrollFromSource.png")) {
public boolean isSelected(AnActionEvent event) {
return isAutoScrollMode();
}
return new AutoScrollFromSourceAction();
}
public void setSelected(AnActionEvent event, boolean flag) {
setAutoScrollMode(flag);
}
};
private class AutoScrollFromSourceAction extends ToggleAction implements DumbAware {
public AutoScrollFromSourceAction() {
super(UIBundle.message("autoscroll.from.source.action.name"), UIBundle.message("autoscroll.from.source.action.description"),
IconLoader.getIcon("/general/autoscrollFromSource.png"));
}
public boolean isSelected(AnActionEvent event) {
return isAutoScrollMode();
}
public void setSelected(AnActionEvent event, boolean flag) {
setAutoScrollMode(flag);
}
}
}