blob: c66bc9fa5a3efc21df76d893301763f863508e13 [file] [log] [blame]
/* Copyright 2008 Edward Yakop.
*
* 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 org.qi4j.ide.plugin.idea.common.intentions;
import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction;
import com.intellij.openapi.editor.CaretModel;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.ReadonlyStatusHandler;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import static org.qi4j.ide.plugin.idea.common.resource.Qi4jResourceBundle.message;
/**
* This class is based from {@code com.siyeh.ipp.base.Intention}
*
* @author edward.yakop@gmail.com
*/
public abstract class AbstractIntention extends PsiElementBaseIntentionAction
{
protected abstract boolean isIntentionValidFor( PsiElement element );
protected abstract String resourceBundlePrefixId();
/**
* Implement this method to process intention.
*
* @param project The project in which the availability is checked.
* @param editor The editor in which the intention will be invoked.
* @param element The element under caret.
*/
protected abstract void processIntention( @NotNull Project project,
@NotNull Editor editor,
@NotNull PsiElement element );
public void invoke( @NotNull Project project, Editor editor, PsiFile file )
throws IncorrectOperationException
{
if( isFileReadOnly( project, file ) )
{
return;
}
final PsiElement element = findMatchingElement( file, editor );
if( element == null )
{
return;
}
processIntention( project, editor, element );
}
protected static boolean isFileReadOnly( @NotNull Project project, @NotNull PsiFile file )
{
VirtualFile virtualFile = file.getVirtualFile();
ReadonlyStatusHandler readonlyStatusHandler = ReadonlyStatusHandler.getInstance( project );
ReadonlyStatusHandler.OperationStatus operationStatus =
readonlyStatusHandler.ensureFilesWritable( virtualFile );
return operationStatus.hasReadonlyFiles();
}
@Nullable
private PsiElement findMatchingElement( @NotNull PsiFile file, @NotNull Editor editor )
{
CaretModel caretModel = editor.getCaretModel();
int position = caretModel.getOffset();
PsiElement element = file.findElementAt( position );
return findMatchingElement( element );
}
@Nullable
private PsiElement findMatchingElement( @Nullable PsiElement element )
{
while( element != null )
{
if( isIntentionValidFor( element ) )
{
return element;
}
else
{
element = element.getParent();
if( element instanceof PsiFile )
{
break;
}
}
}
return null;
}
@Override
public boolean isAvailable( @NotNull Project project, Editor editor, @Nullable PsiElement element )
{
return isIntentionValidFor( element );
}
@NotNull
public final String getFamilyName()
{
return message( resourceBundlePrefixId() + ".family.name" );
}
@NotNull
@Override
public final String getText()
{
return message( resourceBundlePrefixId() + ".name" );
}
}