mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
IDEA-86947 Run configuration list should support drag and drop to reorder the run configurations
This commit is contained in:
@@ -319,6 +319,11 @@ public class ProcessedModulesTable extends JPanel {
|
||||
public void exchangeRows(int oldIndex, int newIndex) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExchangeRows(int oldIndex, int newIndex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void removeElement(Module element) {
|
||||
final boolean reallyRemoved = myElements.remove(element);
|
||||
if (reallyRemoved) {
|
||||
|
||||
@@ -304,6 +304,11 @@ public class ProcessorProfilePanel extends JPanel {
|
||||
public void exchangeRows(int oldIndex, int newIndex) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExchangeRows(int oldIndex, int newIndex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void addRow() {
|
||||
myRows.add(new KeyValuePair());
|
||||
final int index = myRows.size() - 1;
|
||||
@@ -410,6 +415,11 @@ public class ProcessorProfilePanel extends JPanel {
|
||||
public void exchangeRows(int oldIndex, int newIndex) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExchangeRows(int oldIndex, int newIndex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void addRow() {
|
||||
myRows.add("");
|
||||
final int index = myRows.size() - 1;
|
||||
|
||||
+5
@@ -256,6 +256,11 @@ public class ChangeClassSignatureDialog extends RefactoringDialog {
|
||||
fireTableDataChanged();
|
||||
//fireTableRowsUpdated(Math.min(index1, index2), Math.max(index1, index2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExchangeRows(int oldIndex, int newIndex) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private class MyCellRenderer extends ColoredTableCellRenderer {
|
||||
|
||||
@@ -64,6 +64,11 @@ public class ExceptionsTableModel extends AbstractTableModel implements Editable
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExchangeRows(int oldIndex, int newIndex) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getRowCount() {
|
||||
return myTypeCodeFragments.size();
|
||||
}
|
||||
|
||||
@@ -400,6 +400,13 @@ public abstract class ParameterTablePanel extends JPanel {
|
||||
myTable.getSelectionModel().setSelectionInterval(targetRow, targetRow);
|
||||
updateSignature();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExchangeRows(int row, int targetRow) {
|
||||
if (row < 0 || row >= getVariableData().length) return false;
|
||||
if (targetRow < 0 || targetRow >= getVariableData().length) return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private class CheckBoxTableCellRenderer extends BooleanTableCellRenderer {
|
||||
|
||||
@@ -268,5 +268,10 @@ class EditVariableDialog extends DialogWrapper {
|
||||
public void exchangeRows(int oldIndex, int newIndex) {
|
||||
Collections.swap(myVariables, oldIndex, newIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExchangeRows(int oldIndex, int newIndex) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ import com.intellij.util.config.StorageAccessors;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.Convertor;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.ui.EditableModel;
|
||||
import com.intellij.util.ui.GridBag;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.intellij.util.ui.tree.TreeUtil;
|
||||
@@ -77,9 +78,9 @@ class RunConfigurable extends BaseConfigurable {
|
||||
private final Project myProject;
|
||||
private RunDialogBase myRunDialog;
|
||||
@NonNls private final DefaultMutableTreeNode myRoot = new DefaultMutableTreeNode("Root");
|
||||
private final Tree myTree = new Tree(myRoot);
|
||||
private final MyTreeModel myTreeModel = new MyTreeModel(myRoot);
|
||||
private final Tree myTree = new Tree(myTreeModel);
|
||||
private final JPanel myRightPanel = new JPanel(new BorderLayout());
|
||||
private JComponent myToolbarComponent;
|
||||
private final Splitter mySplitter = new Splitter(false);
|
||||
private JPanel myWholePanel;
|
||||
private final StorageAccessors myProperties = StorageAccessors.createGlobal("RunConfigurable");
|
||||
@@ -89,6 +90,7 @@ class RunConfigurable extends BaseConfigurable {
|
||||
private final JCheckBox myConfirmation = new JCheckBox(ExecutionBundle.message("rerun.confirmation.checkbox"), true);
|
||||
private final List<Pair<UnnamedConfigurable, JComponent>> myAdditionalSettings = new ArrayList<Pair<UnnamedConfigurable, JComponent>>();
|
||||
private Map<ConfigurationFactory, Configurable> myStoredComponents = new HashMap<ConfigurationFactory, Configurable>();
|
||||
private ToolbarDecorator myToolbarDecorator;
|
||||
|
||||
public RunConfigurable(final Project project) {
|
||||
this(project, null);
|
||||
@@ -130,7 +132,6 @@ class RunConfigurable extends BaseConfigurable {
|
||||
return o.toString();
|
||||
}
|
||||
});
|
||||
PopupHandler.installFollowingSelectionTreePopup(myTree, createActionsGroup(), ActionPlaces.UNKNOWN, ActionManager.getInstance());
|
||||
myTree.setCellRenderer(new ColoredTreeCellRenderer() {
|
||||
public void customizeCellRenderer(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row,
|
||||
boolean hasFocus) {
|
||||
@@ -415,17 +416,11 @@ class RunConfigurable extends BaseConfigurable {
|
||||
}
|
||||
|
||||
private JPanel createLeftPanel() {
|
||||
final JPanel leftPanel = new JPanel(new BorderLayout());
|
||||
myToolbarComponent = ActionManager.getInstance().
|
||||
createActionToolbar(ActionPlaces.UNKNOWN,
|
||||
createActionsGroup(),
|
||||
true).getComponent();
|
||||
leftPanel.add(myToolbarComponent, BorderLayout.NORTH);
|
||||
initTree();
|
||||
final JScrollPane pane = ScrollPaneFactory.createScrollPane(myTree);
|
||||
pane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
|
||||
leftPanel.add(pane, BorderLayout.CENTER);
|
||||
return leftPanel;
|
||||
DefaultActionGroup actionsGroup = createActionsGroup();
|
||||
PopupHandler.installFollowingSelectionTreePopup(myTree, actionsGroup, ActionPlaces.UNKNOWN, ActionManager.getInstance());
|
||||
myToolbarDecorator = ToolbarDecorator.createDecorator(myTree).setActionGroup(actionsGroup).setForcedDnD();
|
||||
return myToolbarDecorator.createPanel();
|
||||
}
|
||||
|
||||
private JPanel createSettingsPanel() {
|
||||
@@ -990,7 +985,7 @@ class RunConfigurable extends BaseConfigurable {
|
||||
|
||||
});
|
||||
//new TreeSpeedSearch(myTree);
|
||||
popup.showUnderneathOf(myToolbarComponent);
|
||||
popup.showUnderneathOf(myToolbarDecorator.getPanel());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1106,7 +1101,7 @@ class RunConfigurable extends BaseConfigurable {
|
||||
configurable.getNameTextField().setSelectionEnd(copyName.length());
|
||||
}
|
||||
catch (ConfigurationException e1) {
|
||||
Messages.showErrorDialog(myToolbarComponent, e1.getMessage(), e1.getTitle());
|
||||
Messages.showErrorDialog(myToolbarDecorator.getPanel(), e1.getMessage(), e1.getTitle());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1264,4 +1259,57 @@ class RunConfigurable extends BaseConfigurable {
|
||||
|
||||
void clickDefaultButton();
|
||||
}
|
||||
|
||||
private class MyTreeModel extends DefaultTreeModel implements EditableModel {
|
||||
private MyTreeModel(MutableTreeNode root) {
|
||||
super(root);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRow() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeRow(int index) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exchangeRows(int oldIndex, int newIndex) {
|
||||
DefaultMutableTreeNode oldNode = (DefaultMutableTreeNode)myTree.getPathForRow(oldIndex).getLastPathComponent();
|
||||
DefaultMutableTreeNode newNode = (DefaultMutableTreeNode)myTree.getPathForRow(newIndex).getLastPathComponent();
|
||||
DefaultMutableTreeNode parent = (DefaultMutableTreeNode)oldNode.getParent();
|
||||
oldIndex = parent.getIndex(oldNode);
|
||||
newIndex = parent.getIndex(newNode);
|
||||
parent.insert(oldNode, newIndex);
|
||||
parent.insert(newNode, oldIndex);
|
||||
reload(parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExchangeRows(int oldIndex, int newIndex) {
|
||||
DefaultMutableTreeNode oldNode = (DefaultMutableTreeNode)myTree.getPathForRow(oldIndex).getLastPathComponent();
|
||||
DefaultMutableTreeNode newNode = (DefaultMutableTreeNode)myTree.getPathForRow(newIndex).getLastPathComponent();
|
||||
DefaultMutableTreeNode parent = (DefaultMutableTreeNode)oldNode.getParent();
|
||||
if (parent == newNode.getParent()) {
|
||||
RunnerAndConfigurationSettings oldSettings = getSettings(oldNode);
|
||||
RunnerAndConfigurationSettings newSettings = getSettings(newNode);
|
||||
if (oldSettings != null && newSettings != null && oldSettings.isTemporary() == newSettings.isTemporary()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private RunnerAndConfigurationSettings getSettings(@NotNull DefaultMutableTreeNode treeNode) {
|
||||
Object userObject = treeNode.getUserObject();
|
||||
if (userObject instanceof SingleConfigurationConfigurable) {
|
||||
SingleConfigurationConfigurable configurable = (SingleConfigurationConfigurable)userObject;
|
||||
return (RunnerAndConfigurationSettings)configurable.getSettings();
|
||||
} else if (userObject instanceof RunnerAndConfigurationSettings) {
|
||||
return (RunnerAndConfigurationSettings)userObject;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -513,11 +513,21 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable,
|
||||
}
|
||||
}
|
||||
}
|
||||
for (BeforeRunTask task : tasks) {
|
||||
for (int i = 0, size = tasks.size(); i < size; i++) {
|
||||
BeforeRunTask task = tasks.get(i);
|
||||
if (templateTasks != null) {
|
||||
BeforeRunTask templateTask = templateTasks.get(task.getProviderId());
|
||||
if (task.equals(templateTask))
|
||||
continue; // not neccesary saving if the task is the same as template
|
||||
int j = 0;
|
||||
BeforeRunTask templateTask = null;
|
||||
for (Map.Entry<Key<BeforeRunTask>, BeforeRunTask> entry : templateTasks.entrySet()) {
|
||||
if (entry.getKey() == task.getProviderId()) {
|
||||
templateTask = entry.getValue();
|
||||
break;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
if (task.equals(templateTask) && i == j) {
|
||||
continue; // not neccesary saving if the task is the same as template and on the same place
|
||||
}
|
||||
}
|
||||
final Element child = new Element(OPTION);
|
||||
child.setAttribute(NAME_ATTR, task.getProviderId().toString());
|
||||
|
||||
+7
@@ -216,5 +216,12 @@ public abstract class AbstractParameterTablePanel extends JPanel {
|
||||
myTable.getSelectionModel().setSelectionInterval(targetRow, targetRow);
|
||||
updateSignature();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExchangeRows(int row, int targetRow) {
|
||||
if (row < 0 || row >= getVariableData().length) return false;
|
||||
if (targetRow < 0 || targetRow >= getVariableData().length) return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,6 +258,11 @@ public abstract class FileColorSettingsTable extends JBTable {
|
||||
myConfigurations.add(newIndex, myConfigurations.remove(oldIndex));
|
||||
fireTableRowsUpdated(Math.min(oldIndex, newIndex), Math.max(oldIndex, newIndex));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExchangeRows(int oldIndex, int newIndex) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ScopeNameRenderer extends JLabel implements TableCellRenderer {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.intellij.ui;
|
||||
|
||||
import com.intellij.util.ui.EditableModel;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -24,7 +25,7 @@ import java.util.*;
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class CollectionListModel<T> extends AbstractListModel {
|
||||
public class CollectionListModel<T> extends AbstractListModel implements EditableModel {
|
||||
private final List<T> myItems;
|
||||
|
||||
public CollectionListModel(@NotNull final List<? extends T> items) {
|
||||
@@ -99,6 +100,27 @@ public class CollectionListModel<T> extends AbstractListModel {
|
||||
add(elements);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRow() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeRow(int index) {
|
||||
remove(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exchangeRows(int oldIndex, int newIndex) {
|
||||
Collections.swap(myItems, oldIndex, newIndex);
|
||||
fireContentsChanged(this, oldIndex, oldIndex);
|
||||
fireContentsChanged(this, newIndex, newIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExchangeRows(int oldIndex, int newIndex) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getName() + " (" + getSize() + " elements)";
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.intellij.ui;
|
||||
|
||||
import com.intellij.util.ui.EditableModel;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
@@ -111,4 +113,14 @@ class ListToolbarDecorator extends ToolbarDecorator {
|
||||
myList.setVisibleRowCount(rowCount);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isModelEditable() {
|
||||
return myList.getModel() instanceof EditableModel;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installDnDSupport() {
|
||||
RowsDnDSupport.install(myList, (EditableModel)myList.getModel());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.ui;
|
||||
|
||||
import com.intellij.ide.dnd.*;
|
||||
import com.intellij.ui.awt.RelativeRectangle;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.ui.EditableModel;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* @author Konstantin Bulenkov
|
||||
*/
|
||||
public class RowsDnDSupport {
|
||||
private RowsDnDSupport() {
|
||||
}
|
||||
|
||||
public static void install(@NotNull final JTable table, @NotNull final EditableModel model) {
|
||||
table.setDragEnabled(true);
|
||||
installImpl(table, model);
|
||||
}
|
||||
|
||||
public static void install(@NotNull final JList list, @NotNull final EditableModel model) {
|
||||
list.setDragEnabled(true);
|
||||
installImpl(list, model);
|
||||
}
|
||||
|
||||
public static void install(@NotNull final JTree tree, @NotNull final EditableModel model) {
|
||||
tree.setDragEnabled(true);
|
||||
installImpl(tree, model);
|
||||
}
|
||||
|
||||
private static void installImpl(@NotNull final JComponent component, @NotNull final EditableModel model) {
|
||||
DnDSupport.createBuilder(component)
|
||||
.setBeanProvider(new Function<DnDActionInfo, DnDDragStartBean>() {
|
||||
@Override
|
||||
public DnDDragStartBean fun(DnDActionInfo info) {
|
||||
final Point p = info.getPoint();
|
||||
return new DnDDragStartBean(new RowDragInfo(component, Integer.valueOf(getRow(component, p))));
|
||||
}
|
||||
})
|
||||
.setTargetChecker(new DnDTargetChecker() {
|
||||
@Override
|
||||
public boolean update(DnDEvent event) {
|
||||
final Object o = event.getAttachedObject();
|
||||
event.setDropPossible(o instanceof RowDragInfo && ((RowDragInfo)o).component == component);
|
||||
int oldIndex = ((RowDragInfo)o).row;
|
||||
int newIndex = getRow(component, event.getPoint());
|
||||
if (oldIndex != newIndex && newIndex != -1 && model.canExchangeRows(oldIndex, newIndex)) {
|
||||
Rectangle cellBounds = getCellBounds(component, newIndex);
|
||||
if (oldIndex < newIndex) {
|
||||
cellBounds.y += cellBounds.height - 2;
|
||||
}
|
||||
RelativeRectangle rectangle = new RelativeRectangle(component, cellBounds);
|
||||
rectangle.getDimension().height = 2;
|
||||
event.setHighlighting(rectangle, 2);
|
||||
}
|
||||
else {
|
||||
event.setDropPossible(false);
|
||||
event.hideHighlighter();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.setDropHandler(new DnDDropHandler() {
|
||||
@Override
|
||||
public void drop(DnDEvent event) {
|
||||
final Object o = event.getAttachedObject();
|
||||
final Point p = event.getPoint();
|
||||
if (o instanceof RowDragInfo && ((RowDragInfo)o).component == component) {
|
||||
int oldIndex = ((RowDragInfo)o).row;
|
||||
if (oldIndex == -1) return;
|
||||
int newIndex = getRow(component, p);
|
||||
if (newIndex == -1) {
|
||||
newIndex = getRowCount(component) - 1;
|
||||
}
|
||||
if (model.canExchangeRows(oldIndex, newIndex)) {
|
||||
int min = Math.min(oldIndex, newIndex);
|
||||
int max = Math.max(oldIndex, newIndex);
|
||||
if (newIndex > oldIndex) {
|
||||
while (min < max) {
|
||||
model.exchangeRows(min, min + 1);
|
||||
min++;
|
||||
}
|
||||
setSelectedRow(component, min);
|
||||
}
|
||||
else {
|
||||
while (max > min) {
|
||||
model.exchangeRows(max, max - 1);
|
||||
max--;
|
||||
}
|
||||
setSelectedRow(component, max);
|
||||
}
|
||||
}
|
||||
}
|
||||
event.hideHighlighter();
|
||||
}
|
||||
})
|
||||
.install();
|
||||
|
||||
}
|
||||
|
||||
private static int getRow(JComponent component, Point point) {
|
||||
if (component instanceof JTable) {
|
||||
return ((JTable)component).rowAtPoint(point);
|
||||
} else if (component instanceof JList) {
|
||||
return ((JList)component).locationToIndex(point);
|
||||
} else if (component instanceof JTree) {
|
||||
return ((JTree)component).getRowForLocation(point.x, point.y);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unsupported component: " + component);
|
||||
}
|
||||
}
|
||||
|
||||
private static int getRowCount(JComponent component) {
|
||||
if (component instanceof JTable) {
|
||||
return ((JTable)component).getRowCount();
|
||||
} else if (component instanceof JList) {
|
||||
return ((JList)component).getModel().getSize();
|
||||
} else if (component instanceof JTree) {
|
||||
return ((JTree)component).getRowCount();
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unsupported component: " + component);
|
||||
}
|
||||
}
|
||||
|
||||
private static Rectangle getCellBounds(JComponent component, int row) {
|
||||
if (component instanceof JTable) {
|
||||
Rectangle rectangle = ((JTable)component).getCellRect(row, 0, true);
|
||||
rectangle.width = component.getWidth();
|
||||
return rectangle;
|
||||
} else if (component instanceof JList) {
|
||||
return ((JList)component).getCellBounds(row, row);
|
||||
} else if (component instanceof JTree) {
|
||||
return ((JTree)component).getRowBounds(row);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unsupported component: " + component);
|
||||
}
|
||||
}
|
||||
|
||||
private static void setSelectedRow(JComponent component, int row) {
|
||||
if (component instanceof JTable) {
|
||||
((JTable)component).getSelectionModel().setSelectionInterval(row, row);
|
||||
} else if (component instanceof JList) {
|
||||
((JList)component).setSelectedIndex(row);
|
||||
} else if (component instanceof JTree) {
|
||||
((JTree)component).setSelectionRow(row);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unsupported component: " + component);
|
||||
}
|
||||
}
|
||||
|
||||
private static class RowDragInfo {
|
||||
public final JComponent component;
|
||||
public final int row;
|
||||
|
||||
RowDragInfo(JComponent component, int row) {
|
||||
this.component = component;
|
||||
this.row = row;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.ui;
|
||||
|
||||
import com.intellij.ide.dnd.*;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.ui.EditableModel;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.table.TableCellEditor;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* @author Konstantin Bulenkov
|
||||
*/
|
||||
public class TableRowsDnDSupport {
|
||||
private TableRowsDnDSupport() {
|
||||
}
|
||||
|
||||
public static void install(@NotNull final JTable table, @NotNull final EditableModel model) {
|
||||
table.setDragEnabled(true);
|
||||
//table.setDropMode(DropMode.ON);
|
||||
DnDSupport.createBuilder(table)
|
||||
.setBeanProvider(new Function<DnDActionInfo, DnDDragStartBean>() {
|
||||
@Override
|
||||
public DnDDragStartBean fun(DnDActionInfo info) {
|
||||
final Point p = info.getPoint();
|
||||
final TableCellEditor cellEditor = table.getCellEditor();
|
||||
if (cellEditor != null) {
|
||||
cellEditor.stopCellEditing();
|
||||
}
|
||||
return new DnDDragStartBean(new TableRowDragInfo(table, Integer.valueOf(table.rowAtPoint(p))));
|
||||
}
|
||||
})
|
||||
.setTargetChecker(new DnDTargetChecker() {
|
||||
@Override
|
||||
public boolean update(DnDEvent event) {
|
||||
final Object o = event.getAttachedObject();
|
||||
event.setDropPossible(o instanceof TableRowDragInfo && ((TableRowDragInfo)o).table == table);
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.setDropHandler(new DnDDropHandler() {
|
||||
@Override
|
||||
public void drop(DnDEvent event) {
|
||||
final Object o = event.getAttachedObject();
|
||||
final Point p = event.getPoint();
|
||||
if (o instanceof TableRowDragInfo && ((TableRowDragInfo)o).table == table) {
|
||||
int oldIndex = ((TableRowDragInfo)o).row;
|
||||
if (oldIndex == -1) return;
|
||||
int newIndex = table.rowAtPoint(p);
|
||||
if (newIndex == -1) {
|
||||
newIndex = table.getRowCount() - 1;
|
||||
}
|
||||
int min = Math.min(oldIndex, newIndex);
|
||||
int max = Math.max(oldIndex, newIndex);
|
||||
if (newIndex > oldIndex) {
|
||||
while (min < max) {
|
||||
model.exchangeRows(min, min + 1);
|
||||
min++;
|
||||
}
|
||||
table.getSelectionModel().setSelectionInterval(min, min);
|
||||
}
|
||||
else {
|
||||
while (max > min) {
|
||||
model.exchangeRows(max, max - 1);
|
||||
max--;
|
||||
}
|
||||
table.getSelectionModel().setSelectionInterval(max, max);
|
||||
}
|
||||
}
|
||||
}
|
||||
}).install();
|
||||
}
|
||||
|
||||
static class TableRowDragInfo {
|
||||
public final JTable table;
|
||||
public final int row;
|
||||
|
||||
TableRowDragInfo(JTable table, int row) {
|
||||
this.table = table;
|
||||
this.row = row;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.intellij.ui;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.util.ui.EditableModel;
|
||||
import com.intellij.util.ui.ElementProducer;
|
||||
import com.intellij.util.ui.ListTableModel;
|
||||
@@ -39,8 +38,8 @@ class TableToolbarDecorator extends ToolbarDecorator {
|
||||
TableToolbarDecorator(@NotNull JTable table, @Nullable final ElementProducer<?> producer) {
|
||||
myTable = table;
|
||||
myProducer = producer;
|
||||
myAddActionEnabled = myRemoveActionEnabled = myUpActionEnabled = myDownActionEnabled = myTable.getModel() instanceof EditableModel;
|
||||
if (myTable.getModel() instanceof EditableModel) {
|
||||
myAddActionEnabled = myRemoveActionEnabled = myUpActionEnabled = myDownActionEnabled = isModelEditable();
|
||||
if (isModelEditable()) {
|
||||
createDefaultTableActions(producer);
|
||||
}
|
||||
myTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
|
||||
@@ -191,12 +190,11 @@ class TableToolbarDecorator extends ToolbarDecorator {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installDnD() {
|
||||
if (myUpAction != null && myUpActionEnabled
|
||||
&& myDownAction != null && myDownActionEnabled
|
||||
&& !ApplicationManager.getApplication().isHeadlessEnvironment()
|
||||
&& myTable.getModel() instanceof EditableModel) {
|
||||
TableRowsDnDSupport.install(myTable, (EditableModel)myTable.getModel());
|
||||
}
|
||||
protected void installDnDSupport() {
|
||||
RowsDnDSupport.install(myTable, (EditableModel)myTable.getModel());
|
||||
}
|
||||
|
||||
protected boolean isModelEditable() {
|
||||
return myTable.getModel() instanceof EditableModel;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.intellij.ui;
|
||||
|
||||
import com.intellij.ide.DataManager;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.ui.border.CustomLineBorder;
|
||||
@@ -80,12 +81,13 @@ public abstract class ToolbarDecorator implements DataProvider, CommonActionsPan
|
||||
private Comparator<AnActionButton> myButtonComparator;
|
||||
private boolean myAsTopToolbar = false;
|
||||
private Icon myAddIcon;
|
||||
private boolean myForcedDnD = false;
|
||||
|
||||
protected abstract JComponent getComponent();
|
||||
|
||||
protected abstract void updateButtons();
|
||||
|
||||
final CommonActionsPanel getPanel() {
|
||||
public final CommonActionsPanel getPanel() {
|
||||
return myPanel;
|
||||
}
|
||||
|
||||
@@ -273,6 +275,20 @@ public abstract class ToolbarDecorator implements DataProvider, CommonActionsPan
|
||||
return this;
|
||||
}
|
||||
|
||||
public ToolbarDecorator setForcedDnD() {
|
||||
myForcedDnD = true;
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
public ToolbarDecorator setActionGroup(@NotNull ActionGroup actionGroup) {
|
||||
AnAction[] actions = actionGroup.getChildren(null);
|
||||
for (AnAction action : actions) {
|
||||
addExtraAction(AnActionButton.fromAction(action));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public ToolbarDecorator setPreferredSize(Dimension size) {
|
||||
myPreferredSize = size;
|
||||
return this;
|
||||
@@ -354,8 +370,18 @@ public abstract class ToolbarDecorator implements DataProvider, CommonActionsPan
|
||||
}
|
||||
|
||||
protected void installDnD() {
|
||||
if ((myForcedDnD || (myUpAction != null && myUpActionEnabled
|
||||
&& myDownAction != null && myDownActionEnabled))
|
||||
&& !ApplicationManager.getApplication().isHeadlessEnvironment()
|
||||
&& isModelEditable()) {
|
||||
installDnDSupport();
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void installDnDSupport();
|
||||
|
||||
protected abstract boolean isModelEditable();
|
||||
|
||||
@Override
|
||||
public Object getData(@NonNls String dataId) {
|
||||
if (PlatformDataKeys.ACTIONS_SORTER.is(dataId)) {
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.intellij.ui;
|
||||
import com.intellij.openapi.actionSystem.ActionToolbarPosition;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.ui.treeStructure.SimpleNode;
|
||||
import com.intellij.util.ui.EditableModel;
|
||||
import com.intellij.util.ui.EditableTreeModel;
|
||||
import com.intellij.util.ui.ElementProducer;
|
||||
import com.intellij.util.ui.tree.TreeUtil;
|
||||
@@ -123,4 +124,14 @@ class TreeToolbarDecorator extends ToolbarDecorator {
|
||||
myTree.setVisibleRowCount(rowCount);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isModelEditable() {
|
||||
return myTree.getModel() instanceof EditableModel;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installDnDSupport() {
|
||||
RowsDnDSupport.install(myTree, (EditableModel)myTree.getModel());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,6 +85,14 @@ public abstract class JBListTableModel extends AbstractTableModel implements Edi
|
||||
fireTableRowsDeleted(index, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExchangeRows(int oldIndex, int newIndex) {
|
||||
if (myModel instanceof EditableModel) {
|
||||
return ((EditableModel)myModel).canExchangeRows(oldIndex, newIndex);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exchangeRows(int oldIndex, int newIndex) {
|
||||
if (myModel instanceof EditableModel) {
|
||||
|
||||
@@ -25,4 +25,6 @@ public interface EditableModel {
|
||||
void removeRow(int index);
|
||||
|
||||
void exchangeRows(int oldIndex, int newIndex);
|
||||
|
||||
boolean canExchangeRows(int oldIndex, int newIndex);
|
||||
}
|
||||
|
||||
@@ -160,6 +160,11 @@ public class ListTableModel<Item> extends TableViewModel<Item> implements ItemRe
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExchangeRows(int oldIndex, int newIndex) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void addRow(Item item) {
|
||||
myItems.add(item);
|
||||
fireTableRowsInserted(myItems.size() - 1, myItems.size() - 1);
|
||||
|
||||
+4
@@ -71,6 +71,10 @@ public class GrParameterTableModel extends AbstractTableModel implements Editabl
|
||||
fireTableRowsUpdated(Math.min(index1, index2), Math.max(index1, index2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExchangeRows(int oldIndex, int newIndex) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getRowCount() {
|
||||
return infos.size();
|
||||
|
||||
+7
@@ -249,6 +249,13 @@ public abstract class ParameterTablePanel extends JPanel {
|
||||
updateSignature();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExchangeRows(int oldIndex, int newIndex) {
|
||||
if (oldIndex < 0 || newIndex < 0) return false;
|
||||
if (oldIndex >= myParameterInfos.length || newIndex >= myParameterInfos.length) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getRowCount() {
|
||||
return myParameterInfos.length;
|
||||
}
|
||||
|
||||
@@ -102,6 +102,15 @@ public class SvnHistoryProvider
|
||||
@Override
|
||||
protected void updateButtons() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installDnDSupport() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isModelEditable() {
|
||||
return false;
|
||||
}
|
||||
}.initPosition()
|
||||
.addExtraAction(AnActionButton.fromAction(sourceAction))
|
||||
.createPanel();
|
||||
|
||||
Reference in New Issue
Block a user