blob: 71b587b12a7eacba34045c1a6f6677398de00e4d [file] [log] [blame]
/*
* Copyright 2000-2013 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 com.intellij.codeInspection.htmlInspections;
import com.intellij.codeInsight.FileModificationService;
import com.intellij.codeInsight.daemon.XmlErrorMessages;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.XmlTag;
import com.intellij.psi.xml.XmlToken;
import com.intellij.psi.xml.XmlTokenType;
import com.intellij.util.IncorrectOperationException;
import com.intellij.xml.util.XmlTagUtil;
import org.jetbrains.annotations.NotNull;
/**
* @author spleaner
*/
public class RenameTagBeginOrEndIntentionAction implements IntentionAction {
private final boolean myStart;
private final String myTargetName;
private final String mySourceName;
RenameTagBeginOrEndIntentionAction(@NotNull final String targetName, @NotNull final String sourceName, final boolean start) {
myTargetName = targetName;
mySourceName = sourceName;
myStart = start;
}
@Override
@NotNull
public String getFamilyName() {
return getName();
}
@Override
@NotNull
public String getText() {
return getName();
}
@Override
public boolean isAvailable(@NotNull final Project project, final Editor editor, final PsiFile file) {
return true;
}
@Override
public void invoke(@NotNull final Project project, final Editor editor, final PsiFile file) throws IncorrectOperationException {
final int offset = editor.getCaretModel().getOffset();
PsiElement psiElement = file.findElementAt(offset);
if (psiElement == null || !psiElement.isValid()) return;
if (!FileModificationService.getInstance().prepareFileForWrite(psiElement.getContainingFile())) return;
if (psiElement instanceof PsiWhiteSpace) psiElement = PsiTreeUtil.prevLeaf(psiElement);
if (psiElement instanceof XmlToken) {
final IElementType tokenType = ((XmlToken)psiElement).getTokenType();
if (tokenType != XmlTokenType.XML_NAME) {
if (tokenType == XmlTokenType.XML_TAG_END) {
psiElement = psiElement.getPrevSibling();
if (psiElement == null) return;
}
}
PsiElement target = null;
final String text = psiElement.getText();
if (!myTargetName.equals(text)) {
target = psiElement;
}
else {
// we're in the other
PsiElement parent = psiElement.getParent();
if (parent instanceof PsiErrorElement) {
parent = parent.getParent();
}
if (parent instanceof XmlTag) {
if (myStart) {
target = XmlTagUtil.getStartTagNameElement((XmlTag)parent);
}
else {
target = XmlTagUtil.getEndTagNameElement((XmlTag)parent);
if (target == null) {
final PsiErrorElement errorElement = PsiTreeUtil.getChildOfType(parent, PsiErrorElement.class);
target = XmlWrongClosingTagNameInspection.findEndTagName(errorElement);
}
}
}
}
if (target != null) {
final Document document = PsiDocumentManager.getInstance(project).getDocument(file);
if (document != null) {
final TextRange textRange = target.getTextRange();
document.replaceString(textRange.getStartOffset(), textRange.getEndOffset(), myTargetName);
}
}
}
}
@Override
public boolean startInWriteAction() {
return true;
}
@NotNull
public String getName() {
return myStart
? XmlErrorMessages.message("rename.start.tag.name.intention", mySourceName, myTargetName)
: XmlErrorMessages.message("rename.end.tag.name.intention", mySourceName, myTargetName);
}
}