/* * 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(PlatformDataKeys.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; } }