/* * Copyright 2000-2014 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.debugger.settings; import com.intellij.debugger.DebuggerBundle; import com.intellij.debugger.ui.tree.render.CompoundNodeRenderer; import com.intellij.debugger.ui.tree.render.NodeRenderer; import com.intellij.ide.util.ElementsChooser; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.options.ConfigurableUi; import com.intellij.ui.DocumentAdapter; import com.intellij.util.IconUtil; import com.intellij.util.PlatformIcons; import com.intellij.util.containers.InternalIterator; import org.jetbrains.annotations.NotNull; import javax.swing.*; import javax.swing.event.DocumentEvent; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import java.awt.*; import java.util.ArrayList; import java.util.List; public final class UserRenderersConfigurable extends JPanel implements ConfigurableUi { private static final Icon ADD_ICON = IconUtil.getAddIcon(); private static final Icon REMOVE_ICON = IconUtil.getRemoveIcon(); private static final Icon COPY_ICON = PlatformIcons.COPY_ICON; private static final Icon UP_ICON = IconUtil.getMoveUpIcon(); private static final Icon DOWN_ICON = IconUtil.getMoveDownIcon(); private final JPanel myNameFieldPanel; private final JTextField myNameField; private ElementsChooser myRendererChooser; private NodeRenderer myCurrentRenderer = null; private final CompoundRendererConfigurable myRendererDataConfigurable = new CompoundRendererConfigurable(); public UserRenderersConfigurable() { super(new BorderLayout(4, 0)); JPanel left = new JPanel(new BorderLayout()); left.add(createToolbar(), BorderLayout.NORTH); left.add(createRenderersList(), BorderLayout.CENTER); myNameField = new JTextField(); myNameFieldPanel = new JPanel(new BorderLayout()); myNameFieldPanel.add(new JLabel(DebuggerBundle.message("label.user.renderers.configurable.renderer.name")), BorderLayout.WEST); myNameFieldPanel.add(myNameField, BorderLayout.CENTER); myNameFieldPanel.setVisible(false); final JPanel center = new JPanel(new BorderLayout(0, 4)); center.add(myNameFieldPanel, BorderLayout.NORTH); center.add(myRendererDataConfigurable, BorderLayout.CENTER); myNameField.getDocument().addDocumentListener(new DocumentAdapter() { @Override protected void textChanged(DocumentEvent e) { if (myCurrentRenderer != null) { myCurrentRenderer.setName(myNameField.getText()); myRendererChooser.refresh(myCurrentRenderer); } } }); add(left, BorderLayout.WEST); add(center, BorderLayout.CENTER); } @Override @NotNull public JComponent getComponent() { return this; } private JComponent createRenderersList() { myRendererChooser = new ElementsChooser(true); myRendererChooser.getEmptyText().setText(DebuggerBundle.message("text.user.renderers.configurable.no.renderers")); myRendererChooser.addElementsMarkListener(new ElementsChooser.ElementsMarkListener() { @Override public void elementMarkChanged(final NodeRenderer element, final boolean isMarked) { element.setEnabled(isMarked); } }); myRendererChooser.addListSelectionListener(new ListSelectionListener() { @Override public void valueChanged(@NotNull ListSelectionEvent e) { if (!e.getValueIsAdjusting()) { updateCurrentRenderer(myRendererChooser.getSelectedElements()); } } }); return myRendererChooser; } private void updateCurrentRenderer(List selectedElements) { if (selectedElements.size() != 1) { // multi selection setCurrentRenderer(null); } else { setCurrentRenderer(selectedElements.get(0)); } } private void setCurrentRenderer(NodeRenderer renderer) { if (myCurrentRenderer == renderer) { return; } if (myRendererDataConfigurable.isModified()) { myRendererDataConfigurable.apply(); } myCurrentRenderer = renderer; if (renderer != null) { myNameFieldPanel.setVisible(true); myNameField.setText(renderer.getName()); } else { myNameFieldPanel.setVisible(false); myNameField.setText(""); } myRendererDataConfigurable.setRenderer(renderer); } private JComponent createToolbar() { final DefaultActionGroup group = new DefaultActionGroup(); group.add(new AddAction()); group.add(new RemoveAction()); group.add(new CopyAction()); group.add(new MoveAction(true)); group.add(new MoveAction(false)); final ActionToolbar toolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, group, true); return toolbar.getComponent(); } @Override public void apply(@NotNull NodeRendererSettings settings) { myRendererDataConfigurable.apply(); flushTo(settings.getCustomRenderers()); settings.fireRenderersChanged(); } private void flushTo(final RendererConfiguration rendererConfiguration) { final int count = myRendererChooser.getElementCount(); final List renderers = new ArrayList(count); for (int idx = 0; idx < count; idx++) { renderers.add(myRendererChooser.getElementAt(idx)); } rendererConfiguration.setRenderers(renderers); } @Override public boolean isModified(@NotNull NodeRendererSettings settings) { if (myRendererDataConfigurable.isModified()) { return true; } final RendererConfiguration rendererConfiguration = settings.getCustomRenderers(); if (myRendererChooser.getElementCount() != rendererConfiguration.getRendererCount()) { return true; } final RendererConfiguration uiConfiguration = new RendererConfiguration(settings); flushTo(uiConfiguration); return !uiConfiguration.equals(rendererConfiguration); } @Override public void reset(@NotNull NodeRendererSettings settings) { myRendererChooser.removeAllElements(); final RendererConfiguration rendererConfiguration = settings.getCustomRenderers(); final ArrayList elementsToSelect = new ArrayList(1); rendererConfiguration.iterateRenderers(new InternalIterator() { @Override public boolean visit(final NodeRenderer renderer) { final NodeRenderer clonedRenderer = (NodeRenderer)renderer.clone(); myRendererChooser.addElement(clonedRenderer, clonedRenderer.isEnabled()); if (elementsToSelect.size() == 0) { elementsToSelect.add(clonedRenderer); } return true; } }); myRendererChooser.selectElements(elementsToSelect); updateCurrentRenderer(elementsToSelect); myRendererDataConfigurable.reset(); } private class AddAction extends AnAction { public AddAction() { super(DebuggerBundle.message("button.add"), DebuggerBundle.message("user.renderers.configurable.button.description.add"), ADD_ICON); } @Override public void actionPerformed(AnActionEvent e) { final NodeRenderer renderer = (NodeRenderer)NodeRendererSettings.getInstance().createRenderer(CompoundNodeRenderer.UNIQUE_ID); renderer.setEnabled(true); myRendererChooser.addElement(renderer, renderer.isEnabled()); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { myNameField.requestFocus(); } }); } } private class RemoveAction extends AnAction { public RemoveAction() { super(DebuggerBundle.message("button.remove"), DebuggerBundle.message("user.renderers.configurable.button.description.remove"), REMOVE_ICON); } @Override public void actionPerformed(AnActionEvent e) { for (NodeRenderer selectedElement : myRendererChooser.getSelectedElements()) { myRendererChooser.removeElement(selectedElement); } } @Override public void update(AnActionEvent e) { super.update(e); e.getPresentation().setEnabled(myRendererChooser.getSelectedElement() != null); } } private class CopyAction extends AnAction { public CopyAction() { super(DebuggerBundle.message("button.copy"), DebuggerBundle.message("user.renderers.configurable.button.description.copy"), COPY_ICON); } @Override public void actionPerformed(AnActionEvent e) { final NodeRenderer selectedElement = myRendererChooser.getSelectedElement(); if (selectedElement != null) { myRendererChooser.addElement((NodeRenderer)selectedElement.clone(), true); } } @Override public void update(AnActionEvent e) { super.update(e); e.getPresentation().setEnabled(myRendererChooser.getSelectedElement() != null); } } private class MoveAction extends AnAction { private final boolean myMoveUp; public MoveAction(boolean up) { super(up? DebuggerBundle.message("button.move.up") : DebuggerBundle.message("button.move.down"), up? DebuggerBundle.message("user.renderers.configurable.button.description.move.up") : DebuggerBundle.message("user.renderers.configurable.button.description.move.down"), up? UP_ICON : DOWN_ICON ); myMoveUp = up; } @Override public void actionPerformed(AnActionEvent e) { final int selectedRow = myRendererChooser.getSelectedElementRow(); if (selectedRow < 0) { return; } int newRow = selectedRow + (myMoveUp? -1 : 1); if (newRow < 0) { newRow = myRendererChooser.getElementCount() - 1; } else if (newRow >= myRendererChooser.getElementCount()) { newRow = 0; } myRendererChooser.moveElement(myRendererChooser.getElementAt(selectedRow), newRow); } @Override public void update(AnActionEvent e) { super.update(e); e.getPresentation().setEnabled(myRendererChooser.getSelectedElement() != null); } } }