| package com.intellij.tasks.config; |
| |
| import com.intellij.ide.DataManager; |
| import com.intellij.openapi.actionSystem.AnAction; |
| import com.intellij.openapi.actionSystem.AnActionEvent; |
| import com.intellij.openapi.actionSystem.DefaultActionGroup; |
| import com.intellij.openapi.actionSystem.Separator; |
| import com.intellij.openapi.options.BaseConfigurable; |
| import com.intellij.openapi.options.Configurable; |
| import com.intellij.openapi.options.ConfigurationException; |
| import com.intellij.openapi.project.Project; |
| import com.intellij.openapi.roots.ui.configuration.actions.IconWithTextAction; |
| import com.intellij.openapi.ui.Splitter; |
| import com.intellij.openapi.ui.popup.JBPopupFactory; |
| import com.intellij.openapi.util.Disposer; |
| import com.intellij.tasks.TaskManager; |
| import com.intellij.tasks.TaskRepository; |
| import com.intellij.tasks.TaskRepositorySubtype; |
| import com.intellij.tasks.TaskRepositoryType; |
| import com.intellij.tasks.impl.TaskManagerImpl; |
| import com.intellij.ui.*; |
| import com.intellij.ui.components.JBLabel; |
| import com.intellij.ui.components.JBList; |
| import com.intellij.util.Consumer; |
| import com.intellij.util.Function; |
| import com.intellij.util.containers.ConcurrentFactoryMap; |
| import com.intellij.util.containers.ContainerUtil; |
| import com.intellij.util.containers.FactoryMap; |
| import org.jetbrains.annotations.Nls; |
| import org.jetbrains.annotations.Nullable; |
| |
| import javax.swing.*; |
| import javax.swing.event.ListSelectionEvent; |
| import javax.swing.event.ListSelectionListener; |
| import java.awt.*; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.List; |
| import java.util.Set; |
| |
| /** |
| * @author Dmitry Avdeev |
| */ |
| @SuppressWarnings("unchecked") |
| public class TaskRepositoriesConfigurable extends BaseConfigurable implements Configurable.NoScroll { |
| |
| private static final String EMPTY_PANEL = "empty.panel"; |
| private JPanel myPanel; |
| private JPanel myServersPanel; |
| private final JBList myRepositoriesList; |
| @SuppressWarnings({"UnusedDeclaration"}) |
| private JPanel myToolbarPanel; |
| private JPanel myRepositoryEditor; |
| private JBLabel myServersLabel; |
| private Splitter mySplitter; |
| private JPanel myEmptyPanel; |
| |
| private final List<TaskRepository> myRepositories = new ArrayList<TaskRepository>(); |
| private final List<TaskRepositoryEditor> myEditors = new ArrayList<TaskRepositoryEditor>(); |
| private final Project myProject; |
| |
| private final Consumer<TaskRepository> myChangeListener; |
| @SuppressWarnings({"MismatchedQueryAndUpdateOfCollection"}) |
| private final FactoryMap<TaskRepository, String> myRepoNames = new ConcurrentFactoryMap<TaskRepository, String>() { |
| |
| private int count; |
| @Override |
| protected String create(TaskRepository repository) { |
| return Integer.toString(count++); |
| } |
| }; |
| private final TaskManagerImpl myManager; |
| |
| public TaskRepositoriesConfigurable(final Project project) { |
| |
| myProject = project; |
| myManager = (TaskManagerImpl)TaskManager.getManager(project); |
| |
| myRepositoriesList = new JBList(); |
| myRepositoriesList.getEmptyText().setText("No servers"); |
| |
| myServersLabel.setLabelFor(myRepositoriesList); |
| |
| TaskRepositoryType[] groups = TaskManager.ourRepositoryTypes; |
| |
| final List<AnAction> createActions = new ArrayList<AnAction>(); |
| for (final TaskRepositoryType repositoryType : groups) { |
| for (final TaskRepositorySubtype subtype : (List<TaskRepositorySubtype>)repositoryType.getAvailableSubtypes()) { |
| String description = "New " + subtype.getName() + " server"; |
| createActions.add(new IconWithTextAction(subtype.getName(), description, subtype.getIcon()) { |
| @Override |
| public void actionPerformed(AnActionEvent e) { |
| TaskRepository repository = repositoryType.createRepository(subtype); |
| addRepository(repository); |
| } |
| }); |
| } |
| } |
| |
| ToolbarDecorator toolbarDecorator = ToolbarDecorator.createDecorator(myRepositoriesList).disableUpDownActions(); |
| |
| toolbarDecorator.setAddAction(new AnActionButtonRunnable() { |
| @Override |
| public void run(AnActionButton anActionButton) { |
| DefaultActionGroup group = new DefaultActionGroup(); |
| for (AnAction aMyAdditional : createActions) { |
| group.add(aMyAdditional); |
| } |
| Set<TaskRepository> repositories = RecentTaskRepositories.getInstance().getRepositories(); |
| repositories.removeAll(myRepositories); |
| if (!repositories.isEmpty()) { |
| group.add(Separator.getInstance()); |
| for (final TaskRepository repository : repositories) { |
| group.add(new IconWithTextAction(repository.getUrl(), repository.getUrl(), repository.getIcon()) { |
| @Override |
| public void actionPerformed(AnActionEvent e) { |
| addRepository(repository); |
| } |
| }); |
| } |
| } |
| |
| JBPopupFactory.getInstance() |
| .createActionGroupPopup("Add server", group, DataManager.getInstance().getDataContext(anActionButton.getContextComponent()), |
| JBPopupFactory.ActionSelectionAid.SPEEDSEARCH, false).show( |
| anActionButton.getPreferredPopupPoint()); |
| } |
| }); |
| |
| toolbarDecorator.setRemoveAction(new AnActionButtonRunnable() { |
| @Override |
| public void run(AnActionButton anActionButton) { |
| TaskRepository repository = getSelectedRepository(); |
| if (repository != null) { |
| |
| CollectionListModel model = (CollectionListModel)myRepositoriesList.getModel(); |
| model.remove(repository); |
| myRepositories.remove(repository); |
| |
| if (model.getSize() > 0) { |
| myRepositoriesList.setSelectedValue(model.getElementAt(0), true); |
| } |
| else { |
| myRepositoryEditor.removeAll(); |
| myRepositoryEditor.repaint(); |
| } |
| } |
| } |
| }); |
| |
| myServersPanel.add(toolbarDecorator.createPanel(), BorderLayout.CENTER); |
| |
| myRepositoriesList.getSelectionModel().addListSelectionListener(new ListSelectionListener() { |
| public void valueChanged(ListSelectionEvent e) { |
| TaskRepository repository = getSelectedRepository(); |
| if (repository != null) { |
| String name = myRepoNames.get(repository); |
| assert name != null; |
| ((CardLayout)myRepositoryEditor.getLayout()).show(myRepositoryEditor, name); |
| mySplitter.doLayout(); |
| mySplitter.repaint(); |
| } |
| } |
| }); |
| |
| myRepositoriesList.setCellRenderer(new ColoredListCellRenderer() { |
| @Override |
| protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) { |
| TaskRepository repository = (TaskRepository)value; |
| setIcon(repository.getIcon()); |
| append(repository.getPresentableName(), SimpleTextAttributes.REGULAR_ATTRIBUTES); |
| } |
| }); |
| |
| myChangeListener = new Consumer<TaskRepository>() { |
| public void consume(TaskRepository repository) { |
| ((CollectionListModel)myRepositoriesList.getModel()).contentsChanged(repository); |
| } |
| }; |
| } |
| |
| private void addRepository(TaskRepository repository) { |
| myRepositories.add(repository); |
| ((CollectionListModel)myRepositoriesList.getModel()).add(repository); |
| addRepositoryEditor(repository, true); |
| myRepositoriesList.setSelectedIndex(myRepositoriesList.getModel().getSize() - 1); |
| } |
| |
| private void addRepositoryEditor(TaskRepository repository, boolean requestFocus) { |
| TaskRepositoryEditor editor = repository.getRepositoryType().createEditor(repository, myProject, myChangeListener); |
| myEditors.add(editor); |
| JComponent component = editor.createComponent(); |
| String name = myRepoNames.get(repository); |
| myRepositoryEditor.add(component, name); |
| myRepositoryEditor.doLayout(); |
| JComponent preferred = editor.getPreferredFocusedComponent(); |
| if (preferred != null && requestFocus) { |
| // IdeFocusManager.getInstance(myProject).requestFocus(preferred, false); |
| } |
| } |
| |
| @Nullable |
| private TaskRepository getSelectedRepository() { |
| return (TaskRepository)myRepositoriesList.getSelectedValue(); |
| } |
| |
| @Nls |
| public String getDisplayName() { |
| return "Servers"; |
| } |
| |
| public String getHelpTopic() { |
| return "reference.settings.project.tasks.servers"; |
| } |
| |
| public JComponent createComponent() { |
| return myPanel; |
| } |
| |
| @Override |
| public JComponent getPreferredFocusedComponent() { |
| return myRepositoriesList; |
| } |
| |
| public boolean isModified() { |
| return !myRepositories.equals(getReps()); |
| } |
| |
| public void apply() throws ConfigurationException { |
| List<TaskRepository> newRepositories = ContainerUtil.map(myRepositories, new Function<TaskRepository, TaskRepository>() { |
| public TaskRepository fun(TaskRepository taskRepository) { |
| return taskRepository.clone(); |
| } |
| }); |
| myManager.setRepositories(newRepositories); |
| myManager.updateIssues(null); |
| RecentTaskRepositories.getInstance().addRepositories(myRepositories); |
| } |
| |
| public void reset() { |
| myRepoNames.clear(); |
| myRepositoryEditor.removeAll(); |
| myRepositoryEditor.add(myEmptyPanel, EMPTY_PANEL); |
| // ((CardLayout)myRepositoryEditor.getLayout()).show(myRepositoryEditor, ); |
| myRepositories.clear(); |
| |
| CollectionListModel listModel = new CollectionListModel(new ArrayList()); |
| for (TaskRepository repository : myManager.getAllRepositories()) { |
| TaskRepository clone = repository.clone(); |
| assert clone.equals(repository) : repository.getClass().getName(); |
| myRepositories.add(clone); |
| listModel.add(clone); |
| } |
| |
| myRepositoriesList.setModel(listModel); |
| |
| for (TaskRepository clone : myRepositories) { |
| addRepositoryEditor(clone, false); |
| } |
| |
| if (!myRepositories.isEmpty()) { |
| myRepositoriesList.setSelectedValue(myRepositories.get(0), true); |
| } |
| } |
| |
| private List<TaskRepository> getReps() { |
| return Arrays.asList(myManager.getAllRepositories()); |
| } |
| |
| public void disposeUIResources() { |
| for (TaskRepositoryEditor editor : myEditors) { |
| Disposer.dispose(editor); |
| } |
| } |
| } |