update copyright
[fedora-idea.git] / plugins / ui-designer / src / com / intellij / uiDesigner / inspections / NoButtonGroupInspection.java
blob4a3d65da3d7cdddedbdb3f6407bfa9e1288f5874
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.uiDesigner.inspections;
18 import com.intellij.openapi.diagnostic.Logger;
19 import com.intellij.openapi.module.Module;
20 import com.intellij.uiDesigner.FormEditingUtil;
21 import com.intellij.uiDesigner.UIDesignerBundle;
22 import com.intellij.uiDesigner.actions.GroupButtonsAction;
23 import com.intellij.uiDesigner.core.GridConstraints;
24 import com.intellij.uiDesigner.designSurface.GuiEditor;
25 import com.intellij.uiDesigner.lw.IComponent;
26 import com.intellij.uiDesigner.lw.IContainer;
27 import com.intellij.uiDesigner.lw.IRootContainer;
28 import com.intellij.uiDesigner.quickFixes.QuickFix;
29 import com.intellij.uiDesigner.radComponents.RadButtonGroup;
30 import com.intellij.uiDesigner.radComponents.RadComponent;
31 import com.intellij.uiDesigner.radComponents.RadContainer;
32 import com.intellij.uiDesigner.radComponents.RadRootContainer;
33 import org.jetbrains.annotations.NotNull;
35 import javax.swing.*;
36 import java.util.ArrayList;
37 import java.util.Collections;
38 import java.util.Comparator;
40 /**
41 * @author yole
43 public class NoButtonGroupInspection extends BaseFormInspection {
44 private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.inspections.NoButtonGroupInspection");
46 public NoButtonGroupInspection() {
47 super("NoButtonGroup");
50 @NotNull
51 @Override public String getDisplayName() {
52 return UIDesignerBundle.message("inspection.no.button.group");
55 protected void checkComponentProperties(Module module, IComponent component, FormErrorCollector collector) {
56 if (FormInspectionUtil.isComponentClass(module, component, JRadioButton.class)) {
57 final IRootContainer root = FormEditingUtil.getRoot(component);
58 if (root == null) return;
59 if (root.getButtonGroupName(component) == null) {
60 EditorQuickFixProvider quickFixProvider = null;
61 IContainer parent = component.getParentContainer();
62 for(int i=0; i<parent.getComponentCount(); i++) {
63 IComponent child = parent.getComponent(i);
64 if (child != component &&
65 FormInspectionUtil.isComponentClass(module, child, JRadioButton.class)) {
66 final GridConstraints c1 = component.getConstraints();
67 final GridConstraints c2 = child.getConstraints();
68 if (areCellsAdjacent(parent, c1, c2)) {
69 final String groupName = root.getButtonGroupName(child);
70 if (groupName == null) {
71 quickFixProvider = new EditorQuickFixProvider() {
72 public QuickFix createQuickFix(GuiEditor editor, RadComponent component) {
73 return new CreateGroupQuickFix(editor, component, c1.getColumn() == c2.getColumn());
76 break;
78 else {
79 quickFixProvider = new EditorQuickFixProvider() {
80 public QuickFix createQuickFix(GuiEditor editor, RadComponent component) {
81 return new AddToGroupQuickFix(editor, component, groupName);
88 collector.addError(getID(), component, null, UIDesignerBundle.message("inspection.no.button.group.error"), quickFixProvider);
93 private static boolean areCellsAdjacent(final IContainer parent, final GridConstraints c1, final GridConstraints c2) {
94 if (parent instanceof RadContainer) {
95 final RadContainer container = (RadContainer)parent;
96 if (!container.getLayoutManager().isGrid()) return false;
97 if (c1.getRow() == c2.getRow()) {
98 return FormEditingUtil.prevCol(container, c1.getColumn()) == c2.getColumn() ||
99 FormEditingUtil.nextCol(container, c1.getColumn()) == c2.getColumn();
101 if (c1.getColumn() == c2.getColumn()) {
102 return FormEditingUtil.prevRow(container, c1.getRow()) == c2.getRow() ||
103 FormEditingUtil.nextRow(container, c1.getRow()) == c2.getRow();
106 return (c1.getRow() == c2.getRow() && Math.abs(c1.getColumn() - c2.getColumn()) == 1) ||
107 (c1.getColumn() == c2.getColumn() && Math.abs(c1.getRow() - c2.getRow()) == 1);
110 private static class CreateGroupQuickFix extends QuickFix {
111 private final boolean myVerticalGroup;
113 public CreateGroupQuickFix(final GuiEditor editor, final RadComponent component, boolean verticalGroup) {
114 super(editor, UIDesignerBundle.message("inspection.no.button.group.quickfix.create"), component);
115 myVerticalGroup = verticalGroup;
118 public void run() {
119 RadContainer parent = myComponent.getParent();
120 ArrayList<RadComponent> buttonsToGroup = new ArrayList<RadComponent>();
121 for(RadComponent component: parent.getComponents()) {
122 if (FormInspectionUtil.isComponentClass(myComponent.getModule(), component, JRadioButton.class)) {
123 if (component.getConstraints().getCell(!myVerticalGroup) == myComponent.getConstraints().getCell(!myVerticalGroup))
124 buttonsToGroup.add(component);
127 Collections.sort(buttonsToGroup, new Comparator<RadComponent>() {
128 public int compare(final RadComponent o1, final RadComponent o2) {
129 if (myVerticalGroup) {
130 return o1.getConstraints().getRow() - o2.getConstraints().getRow();
132 return o1.getConstraints().getColumn() - o2.getConstraints().getColumn();
136 // ensure that selected radio buttons are in adjacent cells, and exclude from grouping
137 // buttons separated by empty cells or other controls
138 int index=buttonsToGroup.indexOf(myComponent);
139 LOG.assertTrue(index >= 0);
140 int expectCell = myComponent.getConstraints().getCell(myVerticalGroup);
141 for(int i=index-1; i >= 0; i--) {
142 expectCell = FormEditingUtil.adjustForGap(parent, expectCell-1, myVerticalGroup, -1);
143 if (buttonsToGroup.get(i).getConstraints().getCell(myVerticalGroup) != expectCell) {
144 removeRange(buttonsToGroup, 0, i);
145 break;
148 expectCell = myComponent.getConstraints().getCell(myVerticalGroup);
149 for(int i=index+1; i<buttonsToGroup.size(); i++) {
150 expectCell = FormEditingUtil.adjustForGap(parent, expectCell+1, myVerticalGroup, 1);
151 if (buttonsToGroup.get(i).getConstraints().getCell(myVerticalGroup) != expectCell) {
152 removeRange(buttonsToGroup, i, buttonsToGroup.size()-1);
153 break;
157 LOG.assertTrue(buttonsToGroup.size() > 1);
158 GroupButtonsAction.groupButtons(myEditor, buttonsToGroup);
161 private static void removeRange(final ArrayList<RadComponent> buttonsToGroup, final int minIndex, final int maxIndex) {
162 for(int index=maxIndex; index >= minIndex; index--) {
163 buttonsToGroup.remove(index);
168 private static class AddToGroupQuickFix extends QuickFix {
169 private final String myGroupName;
171 public AddToGroupQuickFix(final GuiEditor editor, final RadComponent component, final String groupName) {
172 super(editor, UIDesignerBundle.message("inspection.no.button.group.quickfix.add", groupName), component);
173 myGroupName = groupName;
176 public void run() {
177 RadRootContainer root = (RadRootContainer) FormEditingUtil.getRoot(myComponent);
178 if (root == null) return;
179 for(RadButtonGroup group: root.getButtonGroups()) {
180 if (group.getName().equals(myGroupName)) {
181 root.setGroupForComponent(myComponent, group);
182 break;
185 myEditor.refreshAndSave(true);