ComponentWithBrowseButton - optional remove listener on hide
[fedora-idea.git] / platform / lang-impl / src / com / intellij / codeInsight / generation / surroundWith / SurroundWithHandler.java
blob7efc9cee5cdbb114d2ec178048a512cd638103b7
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.
17 package com.intellij.codeInsight.generation.surroundWith;
19 import com.intellij.codeInsight.CodeInsightActionHandler;
20 import com.intellij.codeInsight.CodeInsightBundle;
21 import com.intellij.codeInsight.template.TemplateManager;
22 import com.intellij.lang.Language;
23 import com.intellij.lang.LanguageSurrounders;
24 import com.intellij.lang.surroundWith.SurroundDescriptor;
25 import com.intellij.lang.surroundWith.Surrounder;
26 import com.intellij.openapi.diagnostic.Logger;
27 import com.intellij.openapi.editor.Editor;
28 import com.intellij.openapi.editor.LogicalPosition;
29 import com.intellij.openapi.editor.ScrollType;
30 import com.intellij.openapi.extensions.Extensions;
31 import com.intellij.openapi.fileEditor.FileDocumentManager;
32 import com.intellij.openapi.project.Project;
33 import com.intellij.openapi.util.TextRange;
34 import com.intellij.psi.PsiDocumentManager;
35 import com.intellij.psi.PsiElement;
36 import com.intellij.psi.PsiFile;
37 import com.intellij.util.IncorrectOperationException;
38 import org.jetbrains.annotations.NotNull;
40 import java.util.ArrayList;
41 import java.util.List;
43 public class SurroundWithHandler implements CodeInsightActionHandler{
44 private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.generation.surroundWith.SurroundWithHandler");
45 private static final String CHOOSER_TITLE = CodeInsightBundle.message("surround.with.chooser.title");
47 public void invoke(@NotNull final Project project, @NotNull final Editor editor, @NotNull PsiFile file){
48 invoke(project, editor, file, null);
51 public boolean startInWriteAction() {
52 return true;
55 public static void invoke(final Project project, final Editor editor, PsiFile file, Surrounder surrounder){
56 if (!editor.getSelectionModel().hasSelection()) {
57 editor.getSelectionModel().selectLineAtCaret();
59 int startOffset = editor.getSelectionModel().getSelectionStart();
60 int endOffset = editor.getSelectionModel().getSelectionEnd();
62 PsiDocumentManager.getInstance(project).commitAllDocuments();
64 PsiElement element1 = file.findElementAt(startOffset);
65 PsiElement element2 = file.findElementAt(endOffset - 1);
67 if (element1 == null || element2 == null) return;
69 TextRange textRange = new TextRange(startOffset, endOffset);
70 for(SurroundWithRangeAdjuster adjuster: Extensions.getExtensions(SurroundWithRangeAdjuster.EP_NAME)) {
71 textRange = adjuster.adjustSurroundWithRange(file, textRange);
72 if (textRange == null) return;
74 startOffset = textRange.getStartOffset();
75 endOffset = textRange.getEndOffset();
76 element1 = file.findElementAt(startOffset);
78 final Language baseLanguage = file.getViewProvider().getBaseLanguage();
79 final Language l = element1.getParent().getLanguage();
80 List<SurroundDescriptor> surroundDescriptors = new ArrayList<SurroundDescriptor>();
82 surroundDescriptors.addAll(LanguageSurrounders.INSTANCE.allForLanguage(l));
83 if (l != baseLanguage) surroundDescriptors.addAll(LanguageSurrounders.INSTANCE.allForLanguage(baseLanguage));
85 for (SurroundDescriptor descriptor : surroundDescriptors) {
86 final PsiElement[] elements = descriptor.getElementsToSurround(file, startOffset, endOffset);
87 if (elements.length > 0) {
88 if (surrounder == null) { //production
89 PopupActionChooser popupActionChooser = new PopupActionChooser(CHOOSER_TITLE);
90 popupActionChooser.invoke(project, editor, file, descriptor.getSurrounders(), elements);
91 if (popupActionChooser.isHasEnabledSurrounders()) return;
93 else {
94 doSurround(project, editor, surrounder, elements);
95 return;
100 if (surrounder == null) { //if only templates are available
101 PopupActionChooser popupActionChooser = new PopupActionChooser(CHOOSER_TITLE);
102 popupActionChooser.invoke(project, editor, file, new Surrounder[0], new PsiElement[0]);
106 static void doSurround(final Project project, final Editor editor, final Surrounder surrounder, final PsiElement[] elements) {
107 final PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
108 if (!FileDocumentManager.getInstance().requestWriting(editor.getDocument(), project)){
109 return;
112 try {
113 PsiDocumentManager.getInstance(project).commitAllDocuments();
114 int col = editor.getCaretModel().getLogicalPosition().column;
115 int line = editor.getCaretModel().getLogicalPosition().line;
116 LogicalPosition pos = new LogicalPosition(0, 0);
117 editor.getCaretModel().moveToLogicalPosition(pos);
118 TextRange range = surrounder.surroundElements(project, editor, elements);
119 if (TemplateManager.getInstance(project).getActiveTemplate(editor) == null) {
120 LogicalPosition pos1 = new LogicalPosition(line, col);
121 editor.getCaretModel().moveToLogicalPosition(pos1);
123 if (range != null) {
124 int offset = range.getStartOffset();
125 editor.getCaretModel().moveToOffset(offset);
126 editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
127 editor.getSelectionModel().setSelection(range.getStartOffset(), range.getEndOffset());
130 catch (IncorrectOperationException e) {
131 LOG.error(e);