Moved educational plugin for PyCharm to community (from github cscenter repository)
[idea/community.git] / platform / platform-impl / src / com / intellij / util / ui / CheckBoxListModelEditor.java
1 /*
2  * Copyright 2000-2014 JetBrains s.r.o.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 package com.intellij.util.ui;
17
18 import com.intellij.ide.IdeBundle;
19 import com.intellij.openapi.actionSystem.AnActionEvent;
20 import com.intellij.openapi.util.Pair;
21 import com.intellij.ui.AnActionButton;
22 import com.intellij.ui.AnActionButtonRunnable;
23 import com.intellij.ui.CheckBoxList;
24 import com.intellij.ui.ToolbarDecorator;
25 import com.intellij.util.Consumer;
26 import com.intellij.util.EditSourceOnDoubleClickHandler;
27 import com.intellij.util.Function;
28 import com.intellij.util.PlatformIcons;
29 import org.jetbrains.annotations.NotNull;
30 import org.jetbrains.annotations.Nullable;
31
32 import javax.swing.*;
33 import java.util.ArrayList;
34 import java.util.List;
35
36 public class CheckBoxListModelEditor<T> {
37   private final CheckBoxList<T> list;
38   private final ToolbarDecorator toolbarDecorator;
39   private final Function<T, String> toNameConverter;
40
41   public CheckBoxListModelEditor(@NotNull Function<T, String> toNameConverter, @NotNull String emptyText) {
42     this.toNameConverter = toNameConverter;
43     list = new CheckBoxList<T>();
44     list.setEmptyText(emptyText);
45     // toolbar decorator is responsible for border
46     list.setBorder(null);
47     toolbarDecorator = ToolbarDecorator.createDecorator(list);
48   }
49
50   @NotNull
51   public CheckBoxListModelEditor<T> editAction(final @NotNull Function<T, T> consumer) {
52     final Runnable action = new Runnable() {
53       @Override
54       public void run() {
55         T item = getSelectedItem();
56         if (item != null) {
57           T newItem = consumer.fun(item);
58           if (newItem != null) {
59             list.updateItem(item, newItem);
60           }
61           list.repaint();
62           list.requestFocus();
63         }
64       }
65     };
66     toolbarDecorator.setEditAction(new AnActionButtonRunnable() {
67       @Override
68       public void run(AnActionButton button) {
69         action.run();
70       }
71     });
72     EditSourceOnDoubleClickHandler.install(list, action);
73     return this;
74   }
75
76   @NotNull
77   public CheckBoxListModelEditor<T> copyAction(final @NotNull Consumer<T> consumer) {
78     toolbarDecorator.addExtraAction(new ToolbarDecorator.ElementActionButton(IdeBundle.message("button.copy"), PlatformIcons.COPY_ICON) {
79       @Override
80       public void actionPerformed(AnActionEvent e) {
81         int[] indices = list.getSelectedIndices();
82         if (indices == null || indices.length == 0) {
83           return;
84         }
85
86         for (int index : indices) {
87           T item = list.getItemAt(index);
88           if (item != null) {
89             consumer.consume(item);
90           }
91         }
92       }
93     });
94     return this;
95   }
96
97   public ToolbarDecorator getToolbar() {
98     return toolbarDecorator;
99   }
100
101   @NotNull
102   public JComponent createComponent() {
103     return toolbarDecorator.createPanel();
104   }
105
106   @NotNull
107   public DefaultListModel getModel() {
108     return ((DefaultListModel)list.getModel());
109   }
110
111   public void selectItemByName(@NotNull String name) {
112     for (int i = 0; i < list.getItemsCount(); i++) {
113       T item = list.getItemAt(i);
114       if (item != null && name.equalsIgnoreCase(toNameConverter.fun(item))) {
115         list.setSelectedIndex(i);
116       }
117     }
118   }
119
120   @Nullable
121   private T getSelectedItem() {
122     int index = list.getSelectedIndex();
123     return index == -1 ? null : list.getItemAt(index);
124   }
125
126   public CheckBoxList<T> getList() {
127     return list;
128   }
129
130   public void reset(@NotNull List<Pair<T, Boolean>> items) {
131     list.clear();
132     for (Pair<T, Boolean> item : items) {
133       list.addItem(item.first, toNameConverter.fun(item.first), item.second);
134     }
135   }
136
137   public boolean isModified(@NotNull List<Pair<T, Boolean>> oldItems) {
138     if (oldItems.size() != list.getItemsCount()) {
139       return true;
140     }
141
142     for (int i = 0; i < list.getItemsCount(); i++) {
143       T item = list.getItemAt(i);
144       if (item == null) {
145         return true;
146       }
147
148       Pair<T, Boolean> oldItem = oldItems.get(i);
149       if (oldItem.second != list.isItemSelected(i) || !oldItem.first.equals(item)) {
150         return true;
151       }
152     }
153     return false;
154   }
155
156   @NotNull
157   public List<T> getItems() {
158     int count = list.getItemsCount();
159     List<T> result = new ArrayList<T>(count);
160     for (int i = 0; i < count; i++) {
161       T item = list.getItemAt(i);
162       if (item != null) {
163         result.add(item);
164       }
165     }
166     return result;
167   }
168
169   @NotNull
170   public List<Pair<T, Boolean>> apply() {
171     int count = list.getItemsCount();
172     List<Pair<T, Boolean>> result = new ArrayList<Pair<T, Boolean>>(count);
173     for (int i = 0; i < count; i++) {
174       T item = list.getItemAt(i);
175       if (item != null) {
176         result.add(Pair.create(item, list.isItemSelected(i)));
177       }
178     }
179     return result;
180   }
181 }