/*
* Copyright 2003-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package jetbrains.mps.ide.projectPane.logicalview;
import jetbrains.mps.ide.ui.smodel.SModelEventsDispatcher;
import jetbrains.mps.ide.ui.tree.MPSTree;
import jetbrains.mps.ide.ui.tree.MPSTreeNode;
import jetbrains.mps.ide.ui.tree.MPSTreeNodeListener;
import jetbrains.mps.ide.ui.tree.smodel.SModelTreeNode;
import jetbrains.mps.project.Project;
import jetbrains.mps.smodel.event.SModelEvent;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.mps.openapi.model.EditableSModel;
import org.jetbrains.mps.openapi.model.SModel;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Tracks SModelTreeNodes and updates (with ModelStructureUpdate help) tree structure according to model changes.
* @author Artem Tikhomirov
*/
class TreeStructureUpdate implements MPSTreeNodeListener {
private final ProjectTree myProjectTree;
private final SModelEventsDispatcher myEventsListener = new SModelEventsDispatcher();
private final Map<SModelTreeNode, ModelChangeListener> myListeners = new HashMap<SModelTreeNode, ModelChangeListener>();
public TreeStructureUpdate(ProjectTree projectTree) {
myProjectTree = projectTree;
}
public void init() {
myProjectTree.addTreeNodeListener(this);
}
public void dispose() {
myProjectTree.removeTreeNodeListener(this);
myEventsListener.dispose();
}
@Override
public void treeNodeAdded(MPSTreeNode treeNode, MPSTree tree) {
if (treeNode instanceof SModelTreeNode) {
final SModelTreeNode mn = (SModelTreeNode) treeNode;
if (mn.getModel() instanceof EditableSModel) {
assert !myListeners.containsKey(mn);
final ModelChangeListener l = new ModelChangeListener(myProjectTree.getProject(), mn);
myEventsListener.registerListener(l);
myListeners.put(mn, l);
}
}
}
@Override
public void treeNodeRemoved(MPSTreeNode treeNode, MPSTree tree) {
if (treeNode instanceof SModelTreeNode) {
final ModelChangeListener l = myListeners.remove(treeNode);
// might be SModelTreeNode for a !EditableSModel
if (l != null) {
myEventsListener.unregisterListener(l);
}
}
}
@Override
public void treeNodeUpdated(MPSTreeNode treeNode, MPSTree tree) {}
@Override
public void beforeTreeDisposed(MPSTree tree) {}
private static class ModelChangeListener implements SModelEventsDispatcher.SModelEventsListener {
private final Project myProject;
private final SModelTreeNode myTreeNode;
private ModelStructureUpdate myUpdater;
public ModelChangeListener(@NotNull Project project, @NotNull SModelTreeNode treeNode) {
myProject = project;
myTreeNode = treeNode;
}
@NotNull
@Override
public SModel getModelDescriptor() {
return myTreeNode.getModel();
}
@Override
public void eventsHappened(List<SModelEvent> events) {
if (myUpdater == null) {
myUpdater = new ModelStructureUpdate(myProject, myTreeNode);
myUpdater.setDependencyRecorder(myTreeNode.getDependencyRecorder());
}
myUpdater.eventsHappenedInCommand(events);
}
}
}