use of com.intellij.pom.tree.events.TreeChangeEvent in project intellij-community by JetBrains.
the class XmlTagImpl method deleteChildInternal.
@Override
public void deleteChildInternal(@NotNull final ASTNode child) {
final PomModel model = PomManager.getModel(getProject());
final XmlAspect aspect = model.getModelAspect(XmlAspect.class);
if (child.getElementType() == XmlElementType.XML_ATTRIBUTE) {
try {
model.runTransaction(new PomTransactionBase(this, aspect) {
@Override
public PomModelEvent runInner() {
final String name = ((XmlAttribute) child).getName();
XmlTagImpl.super.deleteChildInternal(child);
return XmlAttributeSetImpl.createXmlAttributeSet(model, XmlTagImpl.this, name, null);
}
});
} catch (IncorrectOperationException e) {
LOG.error(e);
}
} else {
final ASTNode treePrev = child.getTreePrev();
final ASTNode treeNext = child.getTreeNext();
super.deleteChildInternal(child);
if (treePrev != null && treeNext != null && treePrev.getElementType() == XmlElementType.XML_TEXT && treeNext.getElementType() == XmlElementType.XML_TEXT) {
final XmlText prevText = (XmlText) treePrev.getPsi();
final XmlText nextText = (XmlText) treeNext.getPsi();
final String newValue = prevText.getValue() + nextText.getValue();
// merging two XmlText-s should be done in one transaction to preserve smart pointers
ChangeUtil.prepareAndRunChangeAction(new ChangeUtil.ChangeAction() {
@Override
public void makeChange(TreeChangeEvent destinationTreeChange) {
PsiElement anchor = prevText.getPrevSibling();
prevText.delete();
nextText.delete();
XmlText text = (XmlText) addAfter(XmlElementFactory.getInstance(getProject()).createDisplayText("x"), anchor);
text.setValue(newValue);
}
}, this);
}
}
}
use of com.intellij.pom.tree.events.TreeChangeEvent in project intellij-community by JetBrains.
the class XmlAspectImpl method update.
@Override
public void update(PomModelEvent event) {
if (!event.getChangedAspects().contains(myTreeAspect))
return;
final TreeChangeEvent changeSet = (TreeChangeEvent) event.getChangeSet(myTreeAspect);
if (changeSet == null)
return;
final ASTNode rootElement = changeSet.getRootElement();
final PsiFile file = (PsiFile) rootElement.getPsi();
if (!(file instanceof XmlFile))
return;
final XmlAspectChangeSetImpl xmlChangeSet = event.registerChangeSetIfAbsent(this, new XmlAspectChangeSetImpl(myModel));
xmlChangeSet.addChangedFile((XmlFile) file);
final ASTNode[] changedElements = changeSet.getChangedElements();
final CharTable table = ((FileElement) changeSet.getRootElement()).getCharTable();
for (ASTNode changedElement : changedElements) {
TreeChange changesByElement = changeSet.getChangesByElement(changedElement);
PsiElement psiElement = null;
while (changedElement != null && (psiElement = changedElement.getPsi()) == null) {
final ASTNode parent = changedElement.getTreeParent();
final ChangeInfoImpl changeInfo = ChangeInfoImpl.create(ChangeInfo.CONTENTS_CHANGED, changedElement);
changeInfo.compactChange(changesByElement);
changesByElement = new TreeChangeImpl(parent);
changesByElement.addChange(changedElement, changeInfo);
changedElement = parent;
}
if (changedElement == null)
continue;
final TreeChange finalChangedElement = changesByElement;
psiElement.accept(new XmlElementVisitor() {
TreeChange myChange = finalChangedElement;
@Override
public void visitElement(PsiElement element) {
final ASTNode child = element.getNode();
final ASTNode treeParent = child.getTreeParent();
if (treeParent == null)
return;
final PsiElement parent = treeParent.getPsi();
final ChangeInfoImpl changeInfo = ChangeInfoImpl.create(ChangeInfo.CONTENTS_CHANGED, child);
changeInfo.compactChange(myChange);
myChange = new TreeChangeImpl(treeParent);
myChange.addChange(child, changeInfo);
parent.accept(this);
}
@Override
public void visitXmlAttribute(XmlAttribute attribute) {
final ASTNode[] affectedChildren = myChange.getAffectedChildren();
String oldName = null;
String oldValue = null;
for (final ASTNode treeElement : affectedChildren) {
final ChangeInfo changeByChild = myChange.getChangeByChild(treeElement);
final int changeType = changeByChild.getChangeType();
if (treeElement.getElementType() == XmlTokenType.XML_NAME) {
if (changeType == ChangeInfo.REMOVED) {
oldName = treeElement.getText();
} else if (changeType == ChangeInfo.REPLACE) {
oldName = ((ReplaceChangeInfo) changeByChild).getReplaced().getText();
}
}
if (treeElement.getElementType() == XmlElementType.XML_ATTRIBUTE_VALUE) {
if (changeType == ChangeInfo.REMOVED) {
oldValue = treeElement.getText();
} else if (changeType == ChangeInfo.REPLACE) {
oldValue = ((ReplaceChangeInfo) changeByChild).getReplaced().getText();
}
}
}
if (oldName != null && !oldName.equals(attribute.getName())) {
xmlChangeSet.add(new XmlAttributeSetImpl(attribute.getParent(), oldName, null));
xmlChangeSet.add(new XmlAttributeSetImpl(attribute.getParent(), attribute.getName(), attribute.getValue()));
} else if (oldValue != null) {
xmlChangeSet.add(new XmlAttributeSetImpl(attribute.getParent(), attribute.getName(), attribute.getValue()));
} else {
xmlChangeSet.add(new XmlElementChangedImpl(attribute));
}
}
@Override
public void visitXmlTag(XmlTag tag) {
ASTNode[] affectedChildren = shortenChange(myChange.getAffectedChildren(), changeSet);
for (final ASTNode treeElement : affectedChildren) {
if (!(treeElement.getPsi() instanceof XmlTagChild)) {
visitElement(tag);
return;
}
}
for (final ASTNode treeElement : affectedChildren) {
final ChangeInfo changeByChild = myChange.getChangeByChild(treeElement);
final int changeType = changeByChild.getChangeType();
final IElementType type = treeElement.getElementType();
if (type == TokenType.WHITE_SPACE)
continue;
/*
if (type == ElementType.XML_NAME) {
final XmlToken xmlToken = (XmlToken)((ReplaceChangeInfo)changeByChild).getReplaced();
xmlChangeSet.add(new XmlTagNameChangedImpl(tag, xmlToken.getText()));
continue;
}
*/
final PsiElement element = treeElement.getPsi();
switch(changeType) {
case ChangeInfo.ADD:
xmlChangeSet.add(new XmlTagChildAddImpl(tag, (XmlTagChild) element));
break;
case ChangeInfo.REMOVED:
treeElement.putUserData(CharTable.CHAR_TABLE_KEY, table);
xmlChangeSet.add(new XmlTagChildRemovedImpl(tag, (XmlTagChild) element));
break;
case ChangeInfo.CONTENTS_CHANGED:
xmlChangeSet.add(new XmlTagChildChangedImpl(tag, (XmlTagChild) element));
break;
case ChangeInfo.REPLACE:
final PsiElement psi = ((ReplaceChangeInfo) changeByChild).getReplaced().getPsi();
if (psi instanceof XmlTagChild) {
final XmlTagChild replaced = (XmlTagChild) psi;
replaced.putUserData(CharTable.CHAR_TABLE_KEY, table);
xmlChangeSet.add(new XmlTagChildRemovedImpl(tag, replaced));
xmlChangeSet.add(new XmlTagChildAddImpl(tag, (XmlTagChild) element));
}
break;
}
}
}
@Override
public void visitXmlDocument(XmlDocument document) {
xmlChangeSet.clear();
xmlChangeSet.add(new XmlDocumentChangedImpl(document));
}
@Override
public void visitFile(PsiFile file) {
final XmlDocument document = ((XmlFile) file).getDocument();
if (document != null) {
xmlChangeSet.clear();
xmlChangeSet.add(new XmlDocumentChangedImpl(document));
}
}
});
}
}
use of com.intellij.pom.tree.events.TreeChangeEvent in project intellij-community by JetBrains.
the class PsiEventWrapperAspect method update.
@Override
public void update(PomModelEvent event) {
final TreeChangeEvent changeSet = (TreeChangeEvent) event.getChangeSet(myTreeAspect);
if (changeSet == null)
return;
sendAfterEvents(changeSet);
}
use of com.intellij.pom.tree.events.TreeChangeEvent in project intellij-community by JetBrains.
the class ChangeUtil method prepareAndRunChangeAction.
public static void prepareAndRunChangeAction(final ChangeAction action, final TreeElement changedElement) {
final FileElement changedFile = TreeUtil.getFileElement(changedElement);
final PsiManager manager = changedFile.getManager();
final PomModel model = PomManager.getModel(manager.getProject());
final TreeAspect treeAspect = model.getModelAspect(TreeAspect.class);
model.runTransaction(new PomTransactionBase(changedElement.getPsi(), treeAspect) {
@Override
public PomModelEvent runInner() {
final PomModelEvent event = new PomModelEvent(model);
final TreeChangeEvent destinationTreeChange = new TreeChangeEventImpl(treeAspect, changedFile);
event.registerChangeSet(treeAspect, destinationTreeChange);
action.makeChange(destinationTreeChange);
changedElement.clearCaches();
if (changedElement instanceof CompositeElement) {
((CompositeElement) changedElement).subtreeChanged();
}
return event;
}
});
}
Aggregations