update copyright
[fedora-idea.git] / java / java-impl / src / com / intellij / refactoring / util / duplicates / DuplicatesImpl.java
blob2080243d3e7ab856c4aeffdb0053d096871897be
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.refactoring.util.duplicates;
18 import com.intellij.codeInsight.folding.CodeFoldingManager;
19 import com.intellij.codeInsight.highlighting.HighlightManager;
20 import com.intellij.openapi.application.ApplicationManager;
21 import com.intellij.openapi.application.ApplicationNamesInfo;
22 import com.intellij.openapi.diagnostic.Logger;
23 import com.intellij.openapi.editor.Editor;
24 import com.intellij.openapi.editor.FoldRegion;
25 import com.intellij.openapi.editor.LogicalPosition;
26 import com.intellij.openapi.editor.ScrollType;
27 import com.intellij.openapi.editor.colors.EditorColors;
28 import com.intellij.openapi.editor.colors.EditorColorsManager;
29 import com.intellij.openapi.editor.markup.RangeHighlighter;
30 import com.intellij.openapi.editor.markup.TextAttributes;
31 import com.intellij.openapi.fileEditor.FileEditorManager;
32 import com.intellij.openapi.fileEditor.OpenFileDescriptor;
33 import com.intellij.openapi.project.Project;
34 import com.intellij.openapi.ui.Messages;
35 import com.intellij.openapi.util.TextRange;
36 import com.intellij.openapi.vfs.VirtualFile;
37 import com.intellij.psi.PsiFile;
38 import com.intellij.refactoring.RefactoringBundle;
39 import com.intellij.refactoring.util.CommonRefactoringUtil;
40 import com.intellij.util.IncorrectOperationException;
42 import java.util.ArrayList;
43 import java.util.List;
45 /**
46 * @author dsl
48 public class DuplicatesImpl {
49 private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.util.duplicates.DuplicatesImpl");
51 private DuplicatesImpl() {}
53 public static void invoke(final Project project, Editor editor, final MatchProvider provider) {
54 final List<Match> duplicates = provider.getDuplicates();
55 int idx = 0;
56 for (final Match match : duplicates) {
57 if (!match.getMatchStart().isValid() || !match.getMatchEnd().isValid()) continue;
58 if (replaceMatch(project, provider, match, editor, ++idx, duplicates.size())) return;
62 public static void invoke(final Project project, final MatchProvider provider) {
63 final List<Match> duplicates = provider.getDuplicates();
64 int idx = 0;
65 for (final Match match : duplicates) {
66 final PsiFile file = match.getFile();
67 final VirtualFile virtualFile = file.getVirtualFile();
68 if (virtualFile == null || !virtualFile.isValid()) return;
69 if (!CommonRefactoringUtil.checkReadOnlyStatus(project, file)) return;
70 final Editor editor = FileEditorManager.getInstance(project).openTextEditor(new OpenFileDescriptor(project, virtualFile), false);
71 LOG.assertTrue(editor != null);
72 if (!match.getMatchStart().isValid() || !match.getMatchEnd().isValid()) continue;
73 if (replaceMatch(project, provider, match, editor, ++idx, duplicates.size())) return;
77 private static boolean replaceMatch(final Project project, final MatchProvider provider, final Match match, final Editor editor,
78 final int idx, final int size) {
79 final ArrayList<RangeHighlighter> highlighters = new ArrayList<RangeHighlighter>();
80 highlightMatch(project, editor, match, highlighters);
81 final TextRange textRange = match.getTextRange();
82 final LogicalPosition logicalPosition = editor.offsetToLogicalPosition(textRange.getStartOffset());
83 expandAllRegionsCoveringRange(project, editor, textRange);
84 editor.getScrollingModel().scrollTo(logicalPosition, ScrollType.MAKE_VISIBLE);
85 String prompt = provider.getConfirmDuplicatePrompt(match);
86 final int matchAnswer = ApplicationManager.getApplication().isUnitTestMode()
87 ? 0
88 : Messages.showYesNoCancelDialog(project, prompt, RefactoringBundle.message("process.duplicates.title", idx, size),
89 Messages.getQuestionIcon());
90 HighlightManager.getInstance(project).removeSegmentHighlighter(editor, highlighters.get(0));
91 if (matchAnswer == 0) {
92 final Runnable action = new Runnable() {
93 public void run() {
94 try {
95 provider.processMatch(match);
97 catch (IncorrectOperationException e) {
98 LOG.error(e);
103 //use outer command
104 ApplicationManager.getApplication().runWriteAction(action);
106 else if (matchAnswer == 2) {
107 return true;
109 return false;
112 private static void expandAllRegionsCoveringRange(final Project project, Editor editor, final TextRange textRange) {
113 final FoldRegion[] foldRegions = CodeFoldingManager.getInstance(project).getFoldRegionsAtOffset(editor, textRange.getStartOffset());
114 boolean anyCollapsed = false;
115 for (final FoldRegion foldRegion : foldRegions) {
116 if (!foldRegion.isExpanded()) {
117 anyCollapsed = true;
118 break;
121 if (anyCollapsed) {
122 editor.getFoldingModel().runBatchFoldingOperation(new Runnable() {
123 public void run() {
124 for (final FoldRegion foldRegion : foldRegions) {
125 if (!foldRegion.isExpanded()) {
126 foldRegion.setExpanded(true);
134 public static void highlightMatch(final Project project, Editor editor, final Match match, final ArrayList<RangeHighlighter> highlighters) {
135 EditorColorsManager colorsManager = EditorColorsManager.getInstance();
136 TextAttributes attributes = colorsManager.getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES);
137 HighlightManager.getInstance(project).addRangeHighlight(editor, match.getTextRange().getStartOffset(), match.getTextRange().getEndOffset(),
138 attributes, true, highlighters);
141 public static void processDuplicates(final MatchProvider provider, final Project project, Editor editor) {
142 boolean hasDuplicates = provider.hasDuplicates();
143 if (hasDuplicates) {
144 final int answer = Messages.showYesNoDialog(project,
145 RefactoringBundle.message("0.has.detected.1.code.fragments.in.this.file.that.can.be.replaced.with.a.call.to.extracted.method",
146 ApplicationNamesInfo.getInstance().getProductName(), provider.getDuplicates().size()),
147 "Process Duplicates", Messages.getQuestionIcon());
148 if (answer == 0) {
149 invoke(project, editor, provider);