/* * Copyright 2000-2012 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.application.options.codeStyle.arrangement.group; import com.intellij.psi.codeStyle.arrangement.std.ArrangementStandardSettingsManager; import com.intellij.application.options.codeStyle.arrangement.color.ArrangementColorsProvider; import com.intellij.application.options.codeStyle.arrangement.ui.ArrangementEditorAware; import com.intellij.application.options.codeStyle.arrangement.ui.ArrangementRepresentationAware; import com.intellij.openapi.actionSystem.DataKey; import com.intellij.psi.codeStyle.arrangement.group.ArrangementGroupingRule; import com.intellij.psi.codeStyle.arrangement.std.ArrangementSettingsToken; import com.intellij.psi.codeStyle.arrangement.std.CompositeArrangementSettingsToken; import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.table.JBTable; import com.intellij.util.containers.ContainerUtilRt; import com.intellij.util.ui.AbstractTableCellEditor; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableCellRenderer; import java.awt.*; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; /** * @author Denis Zhdanov * @since 11/13/12 7:27 PM */ public class ArrangementGroupingRulesControl extends JBTable { @NotNull public static final DataKey<ArrangementGroupingRulesControl> KEY = DataKey.create("Arrangement.Rule.Group.Control"); @NotNull private final Map<ArrangementSettingsToken, ArrangementGroupingComponent> myComponents = ContainerUtilRt.newHashMap(); @NotNull private final ArrangementStandardSettingsManager mySettingsManager; private int myRowUnderMouse = -1; public ArrangementGroupingRulesControl(@NotNull ArrangementStandardSettingsManager settingsManager, @NotNull ArrangementColorsProvider colorsProvider) { super(new DefaultTableModel(0, 1)); mySettingsManager = settingsManager; setDefaultRenderer(Object.class, new MyRenderer()); getColumnModel().getColumn(0).setCellEditor(new MyEditor()); setShowColumns(false); setShowGrid(false); setBorder(IdeBorderFactory.createBorder()); setSelectionMode(ListSelectionModel.SINGLE_SELECTION); putClientProperty("terminateEditOnFocusLost", Boolean.TRUE); List<CompositeArrangementSettingsToken> groupingTokens = settingsManager.getSupportedGroupingTokens(); if (groupingTokens != null) { for (CompositeArrangementSettingsToken token : groupingTokens) { ArrangementGroupingComponent component = new ArrangementGroupingComponent(token, colorsProvider, settingsManager); myComponents.put(token.getToken(), component); getModel().addRow(new Object[]{component}); } } } @Override public DefaultTableModel getModel() { return (DefaultTableModel)super.getModel(); } public void setRules(@Nullable List<ArrangementGroupingRule> rules) { for (ArrangementGroupingComponent component : myComponents.values()) { component.setSelected(false); } if (rules == null) { return; } DefaultTableModel model = getModel(); while (model.getRowCount() > 0) { model.removeRow(model.getRowCount() - 1); } final Set<ArrangementSettingsToken> groupingTokens = ContainerUtilRt.newHashSet(myComponents.keySet()); for (ArrangementGroupingRule rule : rules) { final ArrangementSettingsToken groupingType = rule.getGroupingType(); ArrangementGroupingComponent component = myComponents.get(groupingType); component.setSelected(true); component.setOrderType(rule.getOrderType()); model.addRow(new Object[]{component}); groupingTokens.remove(groupingType); } List<ArrangementSettingsToken> types = ContainerUtilRt.newArrayList(groupingTokens); types = mySettingsManager.sort(types); for (ArrangementSettingsToken type : types) { model.addRow(new Object[]{myComponents.get(type)}); } } @NotNull public List<ArrangementGroupingRule> getRules() { List<ArrangementGroupingRule> result = new ArrayList<>(); DefaultTableModel model = getModel(); for (int i = 0, max = model.getRowCount(); i < max; i++) { ArrangementGroupingComponent component = (ArrangementGroupingComponent)model.getValueAt(i, 0); if (!component.isSelected()) { continue; } ArrangementSettingsToken orderType = component.getOrderType(); if (orderType == null) { result.add(new ArrangementGroupingRule(component.getGroupingType())); } else { result.add(new ArrangementGroupingRule(component.getGroupingType(), orderType)); } } return result; } @Override protected void processMouseMotionEvent(MouseEvent e) { if (e.getID() == MouseEvent.MOUSE_MOVED) { int oldRow = myRowUnderMouse; myRowUnderMouse = rowAtPoint(e.getPoint()); if (oldRow >= 0 && myRowUnderMouse != oldRow) { getModel().fireTableRowsUpdated(oldRow, oldRow); } if (myRowUnderMouse >= 0 && myRowUnderMouse != oldRow) { getModel().fireTableRowsUpdated(myRowUnderMouse, myRowUnderMouse); } } super.processMouseMotionEvent(e); } @Override protected void processMouseEvent(MouseEvent e) { if (e.getID() == MouseEvent.MOUSE_EXITED && myRowUnderMouse >= 0) { int row = myRowUnderMouse; myRowUnderMouse = -1; getModel().fireTableRowsUpdated(row, row); } super.processMouseEvent(e); } @SuppressWarnings("ConstantConditions") private class MyRenderer implements TableCellRenderer { @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { if (value instanceof ArrangementGroupingComponent) { ArrangementGroupingComponent component = (ArrangementGroupingComponent)value; component.setRowIndex(row + 1); component.setHighlight(myRowUnderMouse == row || table.isRowSelected(row)); return component; } else if (value instanceof ArrangementRepresentationAware) { return ((ArrangementRepresentationAware)value).getComponent(); } return null; } } @SuppressWarnings("ConstantConditions") private static class MyEditor extends AbstractTableCellEditor { @Nullable Object myValue; @Override public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { if (value instanceof ArrangementEditorAware) { myValue = value; return ((ArrangementEditorAware)value).getComponent(); } return null; } @Override public Object getCellEditorValue() { return myValue; } @Override public boolean stopCellEditing() { super.stopCellEditing(); myValue = null; return true; } } }