package org.freeplane.plugin.formula;
import java.util.List;
import org.freeplane.features.attribute.NodeAttributeTableModel;
import org.freeplane.features.map.IMapChangeListener;
import org.freeplane.features.map.INodeChangeListener;
import org.freeplane.features.map.MapChangeEvent;
import org.freeplane.features.map.NodeChangeEvent;
import org.freeplane.features.map.NodeModel;
import org.freeplane.features.mode.Controller;
import org.freeplane.features.mode.ModeController;
import org.freeplane.features.styles.LogicalStyleModel;
import org.freeplane.features.text.DetailTextModel;
import org.freeplane.features.text.IContentTransformer;
import org.freeplane.plugin.script.FormulaUtils;
/** cares for updating formula nodes on change of other nodes. */
public class FormulaUpdateChangeListener implements INodeChangeListener, IMapChangeListener{
public void nodeChanged(NodeChangeEvent event) {
Object property = event.getProperty();
// Note: this doesn't mean that other properties are not interesting here (e.g. links, edges, ...)
// since all these could be referenced by formulas too. It's restricted only to limit the number of updates.
// ALTERNATIVE: property.getClass() == Class.class && IExtension.class.isAssignableFrom((Class<?>)property)
if (NodeModel.NODE_TEXT.equals(property) || NodeAttributeTableModel.class.equals(property)
|| NodeModel.NOTE_TEXT.equals(property) || NodeModel.NODE_ICON.equals(property)
|| LogicalStyleModel.class.equals(property) || DetailTextModel.class.equals(property)) {
nodeChangedImpl(false, event.getNode());
}
}
public void onNodeDeleted(NodeModel parent, NodeModel child, int index) {
nodeChangedImpl(true, parent);
}
public void onNodeInserted(NodeModel parent, NodeModel child, int newIndex) {
// all formulas dependent on the child via getChildren() are also dependent on its parent
nodeChangedImpl(true, parent);
}
public void onNodeMoved(NodeModel oldParent, int oldIndex, NodeModel newParent, NodeModel child, int newIndex) {
// - all formulas dependent on the child via getChildren() are also dependent on its parent
// FIXME: is child updated or do we have to force that here?
nodeChangedImpl(true, oldParent, newParent);
}
public void onPreNodeMoved(NodeModel oldParent, int oldIndex, NodeModel newParent, NodeModel child, int newIndex) {
}
public void onPreNodeDelete(NodeModel oldParent, NodeModel selectedNode, int index) {
}
public void mapChanged(MapChangeEvent event) {
}
/** in case of insert we look for dependencies of the parent. But the parent is not actually changed in this case.
* So there won't be any updates on the parent, even if it has formula that needs an update due to the
* changed children count. */
private void nodeChangedImpl(boolean includeChanged, NodeModel... nodes) {
final ModeController modeController = Controller.getCurrentModeController();
//FIXME: needed???
// if (modeController == null || modeController.isUndoAction()) {
// return;
// }
final List<NodeModel> dependencies = FormulaUtils.manageChangeAndReturnDependencies(includeChanged, nodes);
for (NodeModel dependentNode : dependencies) {
modeController.getMapController().delayedNodeRefresh(dependentNode, IContentTransformer.class,
null, null);
}
}
}