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.
18 * Created by IntelliJ IDEA.
22 * To change template for new class use
23 * Code Style | Class Templates options (Tools | IDE Options).
25 package com
.intellij
.codeInsight
.template
.actions
;
27 import com
.intellij
.codeInsight
.CodeInsightBundle
;
28 import com
.intellij
.codeInsight
.template
.TemplateContextType
;
29 import com
.intellij
.codeInsight
.template
.impl
.EditTemplateDialog
;
30 import com
.intellij
.codeInsight
.template
.impl
.TemplateImpl
;
31 import com
.intellij
.codeInsight
.template
.impl
.TemplateOptionalProcessor
;
32 import com
.intellij
.codeInsight
.template
.impl
.TemplateSettings
;
33 import com
.intellij
.openapi
.actionSystem
.*;
34 import com
.intellij
.openapi
.application
.ApplicationManager
;
35 import com
.intellij
.openapi
.command
.CommandProcessor
;
36 import com
.intellij
.openapi
.editor
.Document
;
37 import com
.intellij
.openapi
.editor
.Editor
;
38 import com
.intellij
.openapi
.editor
.EditorFactory
;
39 import com
.intellij
.openapi
.editor
.RangeMarker
;
40 import com
.intellij
.openapi
.extensions
.Extensions
;
41 import com
.intellij
.openapi
.fileTypes
.FileType
;
42 import com
.intellij
.openapi
.fileTypes
.FileTypeManager
;
43 import com
.intellij
.openapi
.project
.Project
;
44 import com
.intellij
.openapi
.util
.TextRange
;
45 import com
.intellij
.psi
.*;
46 import com
.intellij
.psi
.util
.PsiElementFilter
;
47 import com
.intellij
.psi
.util
.PsiTreeUtil
;
48 import com
.intellij
.util
.containers
.HashMap
;
49 import org
.jetbrains
.annotations
.NonNls
;
53 public class SaveAsTemplateAction
extends AnAction
{
54 public static final @NonNls String JAVA_LANG_PACKAGE_PREFIX
= "java.lang";
56 public void actionPerformed(AnActionEvent e
) {
57 DataContext dataContext
= e
.getDataContext();
58 final Editor editor
= PlatformDataKeys
.EDITOR
.getData(dataContext
);
59 PsiFile file
= LangDataKeys
.PSI_FILE
.getData(dataContext
);
61 final Project project
= file
.getProject();
62 PsiDocumentManager
.getInstance(project
).commitAllDocuments();
64 final TextRange selection
= new TextRange(editor
.getSelectionModel().getSelectionStart(),
65 editor
.getSelectionModel().getSelectionEnd());
66 PsiElement current
= file
.findElementAt(selection
.getStartOffset());
67 int startOffset
= selection
.getStartOffset();
68 while (current
instanceof PsiWhiteSpace
) {
69 current
= current
.getNextSibling();
70 if (current
== null) break;
71 startOffset
= current
.getTextRange().getStartOffset();
74 if (startOffset
>= selection
.getEndOffset()) startOffset
= selection
.getStartOffset();
76 final PsiElement
[] psiElements
= PsiTreeUtil
.collectElements(file
, new PsiElementFilter() {
77 public boolean isAccepted(PsiElement element
) {
78 return selection
.contains(element
.getTextRange()) && element
.getReferences().length
> 0;
82 final Document document
= EditorFactory
.getInstance().createDocument(editor
.getDocument().getText().
83 substring(startOffset
,
84 selection
.getEndOffset()));
85 final int offsetDelta
= startOffset
;
86 CommandProcessor
.getInstance().executeCommand(project
, new Runnable() {
88 ApplicationManager
.getApplication().runWriteAction(new Runnable() {
90 Map
<RangeMarker
, String
> rangeToText
= new HashMap
<RangeMarker
, String
>();
92 for (PsiElement element
: psiElements
) {
93 for (PsiReference reference
: element
.getReferences()) {
94 if (!(reference
instanceof PsiQualifiedReference
) || ((PsiQualifiedReference
) reference
).getQualifier() == null) {
95 String canonicalText
= reference
.getCanonicalText();
96 TextRange referenceRange
= reference
.getRangeInElement();
97 TextRange range
= element
.getTextRange().cutOut(referenceRange
).shiftRight(-offsetDelta
);
98 final String oldText
= range
.substring(document
.getText());
99 if (!canonicalText
.equals(oldText
)) {
100 rangeToText
.put(document
.createRangeMarker(range
), canonicalText
);
106 for (Map
.Entry
<RangeMarker
, String
> entry
: rangeToText
.entrySet()) {
107 document
.replaceString(entry
.getKey().getStartOffset(), entry
.getKey().getEndOffset(), entry
.getValue());
114 TemplateSettings templateSettings
= TemplateSettings
.getInstance();
116 TemplateImpl template
= new TemplateImpl("", document
.getText(), TemplateSettings
.USER_GROUP_NAME
);
118 FileType fileType
= FileTypeManager
.getInstance().getFileTypeByFile(file
.getVirtualFile());
119 for(TemplateContextType contextType
: Extensions
.getExtensions(TemplateContextType
.EP_NAME
)) {
120 template
.getTemplateContext().setEnabled(contextType
, contextType
.isInContext(fileType
));
123 String defaultShortcut
= "";
124 if (templateSettings
.getDefaultShortcutChar() == TemplateSettings
.ENTER_CHAR
) {
125 defaultShortcut
= CodeInsightBundle
.message("template.shortcut.enter");
127 if (templateSettings
.getDefaultShortcutChar() == TemplateSettings
.TAB_CHAR
) {
128 defaultShortcut
= CodeInsightBundle
.message("template.shortcut.tab");
130 if (templateSettings
.getDefaultShortcutChar() == TemplateSettings
.SPACE_CHAR
) {
131 defaultShortcut
= CodeInsightBundle
.message("template.shortcut.space");
134 Map
<TemplateOptionalProcessor
, Boolean
> options
= template
.createOptions();
135 Map
<TemplateContextType
, Boolean
> context
= template
.createContext();
137 EditTemplateDialog dialog
= new EditTemplateDialog(
138 editor
.getComponent(),
139 CodeInsightBundle
.message("dialog.edit.live.template.title"),
141 templateSettings
.getTemplateGroups(),
142 defaultShortcut
, options
, context
);
144 if (!dialog
.isOK()) {
148 template
.applyOptions(options
);
149 template
.applyContext(context
);
150 templateSettings
.addTemplate(template
);
151 templateSettings
.setLastSelectedTemplateKey(template
.getKey());
154 public void update(AnActionEvent e
) {
155 DataContext dataContext
= e
.getDataContext();
156 Editor editor
= PlatformDataKeys
.EDITOR
.getData(dataContext
);
157 PsiFile file
= LangDataKeys
.PSI_FILE
.getData(dataContext
);
159 if (file
== null || editor
== null) {
160 e
.getPresentation().setEnabled(false);
163 e
.getPresentation().setEnabled(editor
.getSelectionModel().hasSelection());