blob: c60efc42609934200dcbf2a5d325f682c83ce098 [file] [log] [blame]
/*
* Copyright 2000-2011 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.
*/
package com.intellij.cvsSupport2.cvsoperations.cvsAdd.ui;
import com.intellij.CvsBundle;
import com.intellij.cvsSupport2.CvsActionPlaces;
import com.intellij.cvsSupport2.cvsoperations.cvsAdd.AddedFileInfo;
import com.intellij.cvsSupport2.keywordSubstitution.KeywordSubstitutionWrapper;
import com.intellij.cvsSupport2.ui.Options;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.project.Project;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.dualView.TreeTableView;
import com.intellij.ui.treeStructure.treetable.ListTreeTableModelOnColumns;
import com.intellij.ui.treeStructure.treetable.TreeTable;
import com.intellij.ui.treeStructure.treetable.TreeTableModel;
import com.intellij.ui.treeStructure.treetable.TreeTableTree;
import com.intellij.util.ui.ColumnInfo;
import com.intellij.util.ui.ComboBoxTableCellRenderer;
import com.intellij.util.ui.table.ComboBoxTableCellEditor;
import com.intellij.util.ui.tree.TreeUtil;
import org.netbeans.lib.cvsclient.command.KeywordSubstitution;
import javax.swing.*;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.tree.DefaultMutableTreeNode;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Observable;
import java.util.Observer;
/**
* author: lesya
*/
public class AddMultipleFilesOptionsDialog extends AbstractAddOptionsDialog {
private final Collection<AddedFileInfo> myRoots;
private final static JCheckBox CHECKBOX = new JCheckBox();
private final ColumnInfo INCLUDED = new ColumnInfo("") {
public Object valueOf(Object object) {
return Boolean.valueOf(((AddedFileInfo)object).included());
}
public Class getColumnClass() {
return Boolean.class;
}
public boolean isCellEditable(Object o) {
return true;
}
public void setValue(Object o, Object aValue) {
final AddedFileInfo node = (AddedFileInfo)o;
node.setIncluded(((Boolean)aValue).booleanValue());
myModel.nodeChanged(node);
}
public int getWidth(JTable table) {
return CHECKBOX.getPreferredSize().width + 4;
}
};
private static final ColumnInfo<AddedFileInfo, AddedFileInfo> FILE =
new ColumnInfo<AddedFileInfo, AddedFileInfo>(CvsBundle.message("add.multiple.files.file.column.name")) {
public AddedFileInfo valueOf(AddedFileInfo object) {
return object;
}
public Class getColumnClass() {
return TreeTableModel.class;
}
public boolean isCellEditable(AddedFileInfo o) {
return true;
}
};
private static final ColumnInfo KEYWORD_SUBSTITUTION = new ColumnInfo(
CvsBundle.message("add.multiple.files.keyword.substitution.column.name")) {
public Object valueOf(Object object) {
return ((AddedFileInfo)object).getKeywordSubstitutionsWithSelection();
}
public boolean isCellEditable(Object o) {
AddedFileInfo addedFileInfo = (AddedFileInfo)o;
if (addedFileInfo.getFile().isDirectory()) return false;
return addedFileInfo.included();
}
public void setValue(Object o, Object aValue) {
final AddedFileInfo fileInfo = (AddedFileInfo)o;
final KeywordSubstitutionWrapper substitutionWrapper = (KeywordSubstitutionWrapper)aValue;
final KeywordSubstitution substitution = substitutionWrapper.getSubstitution();
fileInfo.setKeywordSubstitution(substitution);
}
public TableCellRenderer getRenderer(Object o) {
AddedFileInfo addedFileInfo = (AddedFileInfo)o;
if (addedFileInfo.getFile().isDirectory()) return TABLE_CELL_RENDERER;
return ComboBoxTableCellRenderer.INSTANCE;
}
public TableCellEditor getEditor(Object item) {
return ComboBoxTableCellEditor.INSTANCE;
}
public int getWidth(JTable table) {
return table.getFontMetrics(table.getFont()).stringWidth(getName()) + 10;
}
};
private final ColumnInfo[] COLUMNS = new ColumnInfo[]{INCLUDED, FILE, KEYWORD_SUBSTITUTION};
private TreeTable myTreeTable;
private ListTreeTableModelOnColumns myModel;
private static final JPanel J_PANEL = new JPanel();
private static final TableCellRenderer TABLE_CELL_RENDERER = new TableCellRenderer() {
public Component getTableCellRendererComponent(JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row,
int column) {
J_PANEL.setBackground(isSelected ? table.getSelectionBackground() : table.getBackground());
return J_PANEL;
}
};
private final Observer myObserver;
public AddMultipleFilesOptionsDialog(Project project, Collection<AddedFileInfo> roots, Options options) {
super(project, options);
myRoots = roots;
myObserver = new Observer() {
public void update(Observable o, Object arg) {
setOKButtonEnabling();
}
};
for (AddedFileInfo myRoot : myRoots) {
myRoot.addIncludedObserver(myObserver);
}
setTitle(CvsBundle.message("dialog.title.add.files.to.cvs"));
createTree();
expandAll();
init();
setOKButtonEnabling();
}
private void setOKButtonEnabling() {
setOKActionEnabled(hasIncludedNodes());
}
private boolean hasIncludedNodes() {
for (AddedFileInfo addedFileInfo : myRoots) {
if (addedFileInfo.hasIncludedNodes()) return true;
}
return false;
}
public void dispose() {
super.dispose();
for (AddedFileInfo myRoot : myRoots) {
myRoot.removeIncludedObserver(myObserver);
}
}
private void expandAll() {
int row = 0;
JTree tree = myTreeTable.getTree();
while (row < tree.getRowCount()) {
tree.expandRow(row);
row++;
}
}
private void createTree() {
DefaultMutableTreeNode root = new DefaultMutableTreeNode();
for (AddedFileInfo myRoot : myRoots) {
root.add(myRoot);
}
myModel = new ListTreeTableModelOnColumns(root, COLUMNS);
myTreeTable = new TreeTableView(myModel);
int comboHeight = new JComboBox().getPreferredSize().height;
int checkBoxHeight = new JCheckBox().getPreferredSize().height;
myTreeTable.setMinRowHeight(Math.max(comboHeight, checkBoxHeight) + 2);
myTreeTable.setRootVisible(false);
final JTableHeader tableHeader = myTreeTable.getTableHeader();
tableHeader.setReorderingAllowed(false);
tableHeader.setResizingAllowed(false);
final TreeTableTree tree = myTreeTable.getTree();
myTreeTable.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
final int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_SPACE) {
final int selectedColumn = myTreeTable.getSelectedColumn();
if (selectedColumn == 0) {
return;
}
final int[] selectedRows = myTreeTable.getSelectedRows();
if (selectedRows.length == 0) {
return;
}
final boolean included = !((AddedFileInfo)myTreeTable.getValueAt(selectedRows[0], 1)).included();
for (int selectedRow : selectedRows) {
final AddedFileInfo addedFileInfo = (AddedFileInfo)myTreeTable.getValueAt(selectedRow, 1);
addedFileInfo.setIncluded(included);
myModel.nodeChanged(addedFileInfo);
}
}
}
});
tree.setCellRenderer(new AddedFileCellRenderer());
TreeUtil.installActions(tree);
}
protected JComponent createCenterPanel() {
JPanel result = new JPanel(new BorderLayout());
JComponent toolbar = createToolbar();
result.add(toolbar, BorderLayout.NORTH);
result.add(ScrollPaneFactory.createScrollPane(myTreeTable), BorderLayout.CENTER);
return result;
}
private JComponent createToolbar() {
ActionManager actionManager = ActionManager.getInstance();
DefaultActionGroup group = new DefaultActionGroup();
group.add(new SelectAllAction());
group.add(new UnselectAllAction());
return actionManager.createActionToolbar(CvsActionPlaces.ADD_FILES_TOOLBAR, group, true).getComponent();
}
private abstract class SelectUnselectAllAction extends AnAction {
protected SelectUnselectAllAction(String text, Icon icon) {
super(text, null, icon);
}
public void actionPerformed(AnActionEvent e) {
for (AddedFileInfo addedFileInfo : getAllFileInfos()) {
addedFileInfo.setIncluded(includedValue());
}
AddMultipleFilesOptionsDialog.this.myTreeTable.repaint();
}
private Collection<AddedFileInfo> getAllFileInfos() {
ArrayList<AddedFileInfo> result = new ArrayList();
for (AddedFileInfo myRoot : myRoots) {
addChildrenTo(result, myRoot);
}
return result;
}
private void addChildrenTo(ArrayList<AddedFileInfo> result, AddedFileInfo addedFileInfo) {
result.add(addedFileInfo);
for (int i = 0; i < addedFileInfo.getChildCount(); i++) {
addChildrenTo(result, (AddedFileInfo)addedFileInfo.getChildAt(i));
}
}
protected abstract boolean includedValue();
}
private class SelectAllAction extends SelectUnselectAllAction {
public SelectAllAction() {
super(CvsBundle.message("action.name.select.all"), AllIcons.Actions.Selectall);
}
protected boolean includedValue() {
return true;
}
}
private class UnselectAllAction extends SelectUnselectAllAction {
public UnselectAllAction() {
super(CvsBundle.message("action.name.unselect.all"), AllIcons.Actions.Unselectall);
}
protected boolean includedValue() {
return false;
}
}
}