blob: 6ec7f0785aaa09876bce83e9b8ced0b943f58875 [file] [log] [blame]
/*
* Copyright 2000-2013 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.
*/
/*
* Created by IntelliJ IDEA.
* User: cdr
* Date: Jul 15, 2007
* Time: 4:04:39 PM
*/
package com.intellij.openapi.vfs.encoding;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.ComboBoxAction;
import com.intellij.openapi.actionSystem.impl.SimpleDataContext;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileFilter;
import com.intellij.util.ui.tree.AbstractFileTreeTable;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.tree.DefaultMutableTreeNode;
import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.io.IOException;
import java.nio.charset.Charset;
class EncodingFileTreeTable extends AbstractFileTreeTable<Charset> {
public EncodingFileTreeTable(@NotNull Project project) {
super(project, Charset.class, "Default Encoding", VirtualFileFilter.ALL, false);
reset(EncodingProjectManager.getInstance(project).getAllMappings());
getValueColumn().setCellRenderer(new DefaultTableCellRenderer(){
@Override
public Component getTableCellRendererComponent(final JTable table, final Object value,
final boolean isSelected, final boolean hasFocus, final int row, final int column) {
super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
final Charset t = (Charset)value;
final Object userObject = table.getModel().getValueAt(row, 0);
final VirtualFile file = userObject instanceof VirtualFile ? (VirtualFile)userObject : null;
Pair<Charset, String> check = file == null || file.isDirectory() ? null : EncodingUtil.checkSomeActionEnabled(file);
String failReason = check == null ? null : check.second;
boolean enabled = failReason == null;
// show existing encoding only if it was specified explicitly or it is unchangeable (with reason)
boolean toShow = t != null || failReason != null;
if (toShow) {
Charset existing = check == null ? null : check.first;
String encodingText = t != null ? t.displayName() : existing == null ? "N/A" : existing.displayName();
setText(encodingText + (failReason == null ? "" : " (" + failReason + ")"));
}
setEnabled(enabled);
return this;
}
});
getValueColumn().setCellEditor(new DefaultCellEditor(new JComboBox()){
private VirtualFile myVirtualFile;
{
delegate = new EditorDelegate() {
@Override
public void setValue(Object value) {
getTableModel().setValueAt(value, new DefaultMutableTreeNode(myVirtualFile), -1);
}
@Override
public Object getCellEditorValue() {
return getTableModel().getValueAt(new DefaultMutableTreeNode(myVirtualFile), 1);
}
};
}
@Override
public Component getTableCellEditorComponent(JTable table, final Object value, boolean isSelected, int row, int column) {
myVirtualFile = (VirtualFile)table.getModel().getValueAt(row, 0);
byte[] b = null;
try {
b = myVirtualFile == null || myVirtualFile.isDirectory() ? null : myVirtualFile.contentsToByteArray();
}
catch (IOException ignored) {
}
final byte[] bytes = b;
final Document document = myVirtualFile == null ? null : FileDocumentManager.getInstance().getDocument(myVirtualFile);
final ChangeFileEncodingAction cfa = new ChangeFileEncodingAction(true) {
@Override
protected boolean chosen(Document document,
Editor editor,
@NotNull VirtualFile virtualFile,
byte[] bytes,
@NotNull Charset charset) {
getValueColumn().getCellEditor().stopCellEditing();
getTableModel().setValueAt(charset, new DefaultMutableTreeNode(virtualFile), 1);
return true;
}
};
ComboBoxAction changeAction = new ComboBoxAction() {
@NotNull
@Override
protected DefaultActionGroup createPopupActionGroup(JComponent button) {
return cfa.createActionGroup(myVirtualFile, null, document, bytes, "<Clear>");
}
};
Presentation templatePresentation = changeAction.getTemplatePresentation();
JComponent comboComponent = changeAction.createCustomComponent(templatePresentation);
DataContext dataContext = SimpleDataContext.getSimpleContext(CommonDataKeys.VIRTUAL_FILE.getName(), myVirtualFile,
SimpleDataContext.getProjectContext(getProject()));
AnActionEvent event = new AnActionEvent(null, dataContext, ActionPlaces.UNKNOWN, templatePresentation, ActionManager.getInstance(), 0);
changeAction.update(event);
templatePresentation.setDescription(null);
if (myVirtualFile == null) {
templatePresentation.setEnabled(true); // enable changing encoding for tree root (entire project)
}
editorComponent = comboComponent;
comboComponent.addComponentListener(new ComponentAdapter() {
@Override
public void componentShown(final ComponentEvent e) {
press((Container)e.getComponent());
}
});
Charset charset = (Charset)getTableModel().getValueAt(new DefaultMutableTreeNode(myVirtualFile), 1);
templatePresentation.setText(charset == null ? "" : charset.displayName());
comboComponent.setToolTipText(null);
comboComponent.revalidate();
return editorComponent;
}
});
}
@Override
protected boolean isNullObject(final Charset value) {
return value == ChooseFileEncodingAction.NO_ENCODING;
}
@Override
protected boolean isValueEditableForFile(final VirtualFile virtualFile) {
return virtualFile == null || virtualFile.isDirectory() ||
EncodingUtil.checkSomeActionEnabled(virtualFile) == null;
}
}