2 * Created by IntelliJ IDEA.
7 package com
.intellij
.openapi
.vfs
.encoding
;
9 import com
.intellij
.openapi
.actionSystem
.AnAction
;
10 import com
.intellij
.openapi
.actionSystem
.AnActionEvent
;
11 import com
.intellij
.openapi
.actionSystem
.DefaultActionGroup
;
12 import com
.intellij
.openapi
.actionSystem
.ex
.ComboBoxAction
;
13 import com
.intellij
.openapi
.editor
.Document
;
14 import com
.intellij
.openapi
.fileEditor
.FileDocumentManager
;
15 import com
.intellij
.openapi
.fileTypes
.FileType
;
16 import com
.intellij
.openapi
.fileTypes
.FileTypeManager
;
17 import com
.intellij
.openapi
.fileTypes
.LanguageFileType
;
18 import com
.intellij
.openapi
.fileTypes
.StdFileTypes
;
19 import com
.intellij
.openapi
.project
.Project
;
20 import com
.intellij
.openapi
.util
.Key
;
21 import com
.intellij
.openapi
.util
.Pair
;
22 import com
.intellij
.openapi
.vfs
.CharsetToolkit
;
23 import com
.intellij
.openapi
.vfs
.VirtualFile
;
24 import org
.jetbrains
.annotations
.NotNull
;
25 import org
.jetbrains
.annotations
.Nullable
;
28 import java
.nio
.charset
.Charset
;
29 import java
.nio
.charset
.CharsetDecoder
;
30 import java
.nio
.charset
.CharsetEncoder
;
31 import java
.util
.ArrayList
;
32 import java
.util
.Arrays
;
33 import java
.util
.Collections
;
34 import java
.util
.List
;
36 public abstract class ChooseFileEncodingAction
extends ComboBoxAction
{
37 private final VirtualFile myVirtualFile
;
38 private final Project myProject
;
40 public ChooseFileEncodingAction(VirtualFile virtualFile
, Project project
) {
41 myVirtualFile
= virtualFile
;
45 public void update(final AnActionEvent e
) {
46 boolean enabled
= isEnabled(myProject
, myVirtualFile
);
47 if (myVirtualFile
!= null) {
49 Charset charset
= encodingFromContent(myProject
, myVirtualFile
);
50 if (charset
!= null) {
56 if (charset
== null) charset
= myVirtualFile
.getCharset();
57 e
.getPresentation().setText(prefix
+ " " + charset
.toString());
59 e
.getPresentation().setEnabled(enabled
);
62 public static boolean isEnabled(Project project
, VirtualFile virtualFile
) {
63 if (project
== null) return false;
64 boolean enabled
= true;
65 if (virtualFile
!= null) {
66 Charset charset
= encodingFromContent(project
, virtualFile
);
67 if (charset
!= null) {
70 else if (!virtualFile
.isDirectory()) {
71 FileType fileType
= FileTypeManager
.getInstance().getFileTypeByFile(virtualFile
);
72 if (fileType
.isBinary()
73 || fileType
== StdFileTypes
.GUI_DESIGNER_FORM
74 || fileType
== StdFileTypes
.IDEA_MODULE
75 || fileType
== StdFileTypes
.IDEA_PROJECT
76 || fileType
== StdFileTypes
.IDEA_WORKSPACE
77 || fileType
== StdFileTypes
.PATCH
78 || fileType
== StdFileTypes
.PROPERTIES
80 || fileType
== StdFileTypes
.XML
81 || fileType
== StdFileTypes
.JSPX
82 || fileType
== StdFileTypes
.XHTML
91 private static final Key
<Pair
<Charset
, Long
>> CACHED_CHARSET_FROM_CONTENT
= Key
.create("CACHED_CHARSET");
92 public static Charset
encodingFromContent(Project project
, VirtualFile virtualFile
) {
93 FileType fileType
= virtualFile
.getFileType();
94 if (fileType
instanceof LanguageFileType
) {
95 Document document
= FileDocumentManager
.getInstance().getDocument(virtualFile
);
96 if (document
== null) return null;
97 Pair
<Charset
, Long
> cachedCharset
= document
.getUserData(CACHED_CHARSET_FROM_CONTENT
);
99 if (cachedCharset
== null || cachedCharset
.getSecond() != document
.getModificationStamp()) {
100 charset
= ((LanguageFileType
)fileType
).extractCharsetFromFileContent(project
, virtualFile
, document
.getText());
101 document
.putUserData(CACHED_CHARSET_FROM_CONTENT
, Pair
.create(charset
, document
.getModificationStamp()));
104 charset
= cachedCharset
.getFirst();
106 if (charset
!= null) {
114 protected DefaultActionGroup
createPopupActionGroup(final JComponent button
) {
115 return createGroup(true);
118 private void fillCharsetActions(DefaultActionGroup group
, final VirtualFile virtualFile
, List
<Charset
> charsets
) {
119 for (Charset slave
: charsets
) {
120 ChangeFileEncodingTo action
= new ChangeFileEncodingTo(virtualFile
, slave
){
121 protected void chosen(final VirtualFile file
, final Charset charset
) {
122 ChooseFileEncodingAction
.this.chosen(file
, charset
);
129 private class ClearThisFileEncodingAction
extends AnAction
{
130 private final VirtualFile myFile
;
132 private ClearThisFileEncodingAction(@Nullable VirtualFile file
) {
133 super("<Clear>", "Clear " +
134 (file
== null ?
"default" : "file '"+file
.getName()+"'") +
139 public void actionPerformed(final AnActionEvent e
) {
140 chosen(myFile
, NO_ENCODING
);
144 public static final Charset NO_ENCODING
= new Charset("NO_ENCODING", null) {
145 public boolean contains(final Charset cs
) {
149 public CharsetDecoder
newDecoder() {
153 public CharsetEncoder
newEncoder() {
157 protected abstract void chosen(VirtualFile virtualFile
, Charset charset
);
159 public DefaultActionGroup
createGroup(boolean showClear
) {
160 DefaultActionGroup group
= new DefaultActionGroup();
161 List
<Charset
> favorites
= new ArrayList
<Charset
>(EncodingManager
.getInstance().getFavorites());
162 Collections
.sort(favorites
);
165 group
.add(new ClearThisFileEncodingAction(myVirtualFile
));
167 fillCharsetActions(group
, myVirtualFile
, favorites
);
169 DefaultActionGroup more
= new DefaultActionGroup("more", true);
171 fillCharsetActions(more
, myVirtualFile
, Arrays
.asList(CharsetToolkit
.getAvailableCharsets()));