| /* |
| * Copyright 2000-2011 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.codeInsight.actions; |
| |
| import com.intellij.codeInsight.CodeInsightBundle; |
| import com.intellij.formatting.FormattingProgressTask; |
| import com.intellij.notification.Notification; |
| import com.intellij.notification.NotificationType; |
| import com.intellij.openapi.application.ApplicationBundle; |
| import com.intellij.openapi.application.ApplicationManager; |
| import com.intellij.openapi.diagnostic.Logger; |
| import com.intellij.openapi.module.Module; |
| import com.intellij.openapi.project.Project; |
| import com.intellij.openapi.util.TextRange; |
| import com.intellij.psi.PsiDirectory; |
| import com.intellij.psi.PsiFile; |
| import com.intellij.psi.codeStyle.CodeStyleManager; |
| import com.intellij.util.IncorrectOperationException; |
| import com.intellij.util.containers.ContainerUtil; |
| import com.intellij.util.diff.FilesTooBigForDiffException; |
| import org.jetbrains.annotations.NotNull; |
| import org.jetbrains.annotations.Nullable; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.concurrent.Callable; |
| import java.util.concurrent.FutureTask; |
| |
| public class ReformatCodeProcessor extends AbstractLayoutCodeProcessor { |
| |
| public static final String COMMAND_NAME = CodeInsightBundle.message("process.reformat.code"); |
| |
| private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.actions.ReformatCodeProcessor"); |
| |
| private final Collection<TextRange> myRanges = new ArrayList<TextRange>(); |
| private static final String PROGRESS_TEXT = CodeInsightBundle.message("reformat.progress.common.text"); |
| |
| public ReformatCodeProcessor(Project project, boolean processChangedTextOnly) { |
| super(project, COMMAND_NAME, PROGRESS_TEXT, processChangedTextOnly); |
| } |
| |
| public ReformatCodeProcessor(Project project, Module module, boolean processChangedTextOnly) { |
| super(project, module, COMMAND_NAME, PROGRESS_TEXT, processChangedTextOnly); |
| } |
| |
| public ReformatCodeProcessor(Project project, PsiDirectory directory, boolean includeSubdirs, boolean processChangedTextOnly) { |
| super(project, directory, includeSubdirs, PROGRESS_TEXT, COMMAND_NAME, processChangedTextOnly); |
| } |
| |
| public ReformatCodeProcessor(Project project, PsiFile file, @Nullable TextRange range, boolean processChangedTextOnly) { |
| super(project, file, PROGRESS_TEXT, COMMAND_NAME, processChangedTextOnly); |
| if (range != null) { |
| myRanges.add(range); |
| } |
| } |
| |
| public ReformatCodeProcessor(Project project, PsiFile[] files, @Nullable Runnable postRunnable, boolean processChangedTextOnly) { |
| this(project, files, COMMAND_NAME, postRunnable, processChangedTextOnly); |
| } |
| |
| public ReformatCodeProcessor(Project project, |
| PsiFile[] files, |
| String commandName, |
| @Nullable Runnable postRunnable, |
| boolean processChangedTextOnly) |
| { |
| super(project, files, PROGRESS_TEXT, commandName, postRunnable, processChangedTextOnly); |
| } |
| |
| @Override |
| @NotNull |
| protected FutureTask<Boolean> prepareTask(@NotNull final PsiFile file, final boolean processChangedTextOnly) |
| throws IncorrectOperationException |
| { |
| return new FutureTask<Boolean>(new Callable<Boolean>() { |
| @Override |
| public Boolean call() throws Exception { |
| FormattingProgressTask.FORMATTING_CANCELLED_FLAG.set(false); |
| try { |
| Collection<TextRange> ranges = getRangesToFormat(processChangedTextOnly, file); |
| CodeStyleManager.getInstance(myProject).reformatText(file, ranges); |
| return !FormattingProgressTask.FORMATTING_CANCELLED_FLAG.get(); |
| } |
| catch (FilesTooBigForDiffException e) { |
| LOG.info("Error while calculating changed ranges for: " + file.getVirtualFile(), e); |
| if (!ApplicationManager.getApplication().isUnitTestMode()) { |
| Notification notification = new Notification(ApplicationBundle.message("reformat.changed.text.file.too.big.notification.groupId"), |
| ApplicationBundle.message("reformat.changed.text.file.too.big.notification.title"), |
| ApplicationBundle.message("reformat.changed.text.file.too.big.notification.text", file.getName()), |
| NotificationType.INFORMATION); |
| notification.notify(file.getProject()); |
| } |
| return false; |
| } |
| catch (IncorrectOperationException e) { |
| LOG.error(e); |
| return false; |
| } |
| finally { |
| myRanges.clear(); |
| } |
| } |
| }); |
| } |
| |
| @NotNull |
| private Collection<TextRange> getRangesToFormat(boolean processChangedTextOnly, PsiFile file) throws FilesTooBigForDiffException { |
| if (processChangedTextOnly) { |
| return FormatChangedTextUtil.getChangedTextRanges(myProject, file); |
| } |
| |
| return !myRanges.isEmpty() ? myRanges : ContainerUtil.newArrayList(file.getTextRange()); |
| } |
| } |