diff --git a/platform/lang-api/src/com/intellij/execution/util/EnvVariablesTable.java b/platform/lang-api/src/com/intellij/execution/util/EnvVariablesTable.java index be4db4d892a4..dc41cef0a1cc 100644 --- a/platform/lang-api/src/com/intellij/execution/util/EnvVariablesTable.java +++ b/platform/lang-api/src/com/intellij/execution/util/EnvVariablesTable.java @@ -16,10 +16,22 @@ package com.intellij.execution.util; +import com.intellij.icons.AllIcons; +import com.intellij.idea.ActionsBundle; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.ide.CopyPasteManager; +import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.ui.AnActionButton; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.ColumnInfo; import com.intellij.util.ui.ListTableModel; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.util.ArrayList; import java.util.List; public class EnvVariablesTable extends ListTableWithButtons { @@ -91,6 +103,61 @@ public class EnvVariablesTable extends ListTableWithButtons return new EnvironmentVariable("", "", false); } + @Override + protected boolean isEmpty(EnvironmentVariable element) { + return element.getName().isEmpty() && element.getValue().isEmpty(); + } + + @Override + protected AnActionButton[] createExtraActions() { + AnActionButton copyButton = new AnActionButton(ActionsBundle.message("action.EditorCopy.text"), AllIcons.Actions.Copy) { + @Override + public void actionPerformed(@NotNull AnActionEvent e) { + stopEditing(); + StringBuilder sb = new StringBuilder(); + List variables = getEnvironmentVariables(); + for (EnvironmentVariable environmentVariable : variables) { + if (environmentVariable.getIsPredefined() || isEmpty(environmentVariable)) continue; + if (sb.length() > 0) sb.append('\n'); + sb.append(StringUtil.escapeChar(environmentVariable.getName(), '=')).append('=') + .append(StringUtil.escapeChar(environmentVariable.getValue(), '=')); + } + CopyPasteManager.getInstance().setContents(new StringSelection(sb.toString())); + } + }; + AnActionButton pasteButton = new AnActionButton(ActionsBundle.message("action.EditorPaste.text"), AllIcons.Actions.Menu_paste) { + @Override + public void actionPerformed(@NotNull AnActionEvent e) { + stopEditing(); + String content = CopyPasteManager.getInstance().getContents(DataFlavor.stringFlavor); + if (content == null || !content.contains("=")) return; + List parsed = new ArrayList(); + List lines = StringUtil.split(content, "\n"); + for (String line : lines) { + int pos = line.indexOf('='); + if (pos == -1) continue; + while (pos > 0 && line.charAt(pos - 1) == '\\') { + pos = line.indexOf('=', pos + 1); + } + parsed.add(new EnvironmentVariable( + StringUtil.unescapeStringCharacters(line.substring(0, pos)), + StringUtil.unescapeStringCharacters(line.substring(pos + 1)), + false)); + } + List variables = + new ArrayList(ContainerUtil.filter(getEnvironmentVariables(), new Condition() { + @Override + public boolean value(EnvironmentVariable variable) { + return variable.getIsPredefined(); + } + })); + variables.addAll(parsed); + setValues(variables); + } + }; + return new AnActionButton[]{copyButton, pasteButton}; + } + @Override protected EnvironmentVariable cloneElement(EnvironmentVariable envVariable) { return envVariable.clone(); diff --git a/platform/lang-api/src/com/intellij/execution/util/ListTableWithButtons.java b/platform/lang-api/src/com/intellij/execution/util/ListTableWithButtons.java index 28491c21fc2d..ef95a9adc0d7 100644 --- a/platform/lang-api/src/com/intellij/execution/util/ListTableWithButtons.java +++ b/platform/lang-api/src/com/intellij/execution/util/ListTableWithButtons.java @@ -29,6 +29,8 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableCellRenderer; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; import java.util.List; import java.util.Observable; @@ -38,17 +40,52 @@ import java.util.Observable; public abstract class ListTableWithButtons extends Observable { private final List myElements = ContainerUtil.newArrayList(); private final JPanel myPanel; - private final TableView myTableView; + private final TableView myTableView; private boolean myIsEnabled = true; protected ListTableWithButtons() { - myTableView = new TableView(createListModel()); + myTableView = new TableView(createListModel()) { + @Override + protected void createDefaultEditors() { + super.createDefaultEditors(); + Object editor = defaultEditorsByColumnClass.get(String.class); + if (editor instanceof DefaultCellEditor) { + ((DefaultCellEditor)editor).getComponent().addKeyListener(new KeyAdapter() { + @Override + public void keyPressed(KeyEvent e) { + final int column = myTableView.getEditingColumn(); + final int row = myTableView.getEditingRow(); + if (e.getModifiers() == 0 && (e.getKeyCode() == KeyEvent.VK_ENTER || e.getKeyCode() == KeyEvent.VK_TAB)) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + stopEditing(); + int nextColumn = column < myTableView.getColumnCount() - 1? column + 1 : 0; + int nextRow = nextColumn == 0 ? row + 1 : row; + if (nextRow > myTableView.getRowCount() - 1) { + if (myElements.isEmpty() || !ListTableWithButtons.this.isEmpty(myElements.get(myElements.size() - 1))) { + ToolbarDecorator.findAddButton(myPanel).actionPerformed(null); + return; + } else { + nextRow = 0; + } + } + myTableView.editCellAt(nextRow, nextColumn); + } + }); + } + } + }); + } + } + }; myTableView.setRowHeight(new JTextField().getPreferredSize().height); myTableView.getTableViewModel().setSortable(false); myPanel = ToolbarDecorator.createDecorator(myTableView) .setAddAction(new AnActionButtonRunnable() { @Override public void run(AnActionButton button) { + if (!myElements.isEmpty() && isEmpty(myElements.get(myElements.size() - 1))) return; myTableView.stopEditing(); setModified(); SwingUtilities.invokeLater(new Runnable() { @@ -56,6 +93,7 @@ public abstract class ListTableWithButtons extends Observable { public void run() { myElements.add(createElement()); myTableView.getTableViewModel().setItems(myElements); + myTableView.scrollRectToVisible(myTableView.getCellRect(myElements.size() - 1, 0, true)); myTableView.getComponent().editCellAt(myElements.size() - 1, 0); } }); @@ -65,7 +103,7 @@ public abstract class ListTableWithButtons extends Observable { public void run(AnActionButton button) { myTableView.stopEditing(); setModified(); - Object selected = getSelection(); + T selected = getSelection(); if (selected != null) { int selectedIndex = myElements.indexOf(selected); myElements.remove(selected); @@ -80,7 +118,7 @@ public abstract class ListTableWithButtons extends Observable { } } } - }).disableUpDownActions().createPanel(); + }).disableUpDownActions().addExtraActions(createExtraActions()).createPanel(); ToolbarDecorator.findRemoveButton(myPanel).addCustomUpdater(new AnActionButtonUpdater() { @Override @@ -135,6 +173,12 @@ public abstract class ListTableWithButtons extends Observable { protected abstract T createElement(); + protected abstract boolean isEmpty(T element); + + protected AnActionButton[] createExtraActions() { + return null; + } + protected T getSelection() { int selIndex = myTableView.getComponent().getSelectionModel().getMinSelectionIndex(); diff --git a/platform/lang-api/src/com/intellij/execution/util/PathMappingTable.java b/platform/lang-api/src/com/intellij/execution/util/PathMappingTable.java index 715263265f17..ce7e79501430 100644 --- a/platform/lang-api/src/com/intellij/execution/util/PathMappingTable.java +++ b/platform/lang-api/src/com/intellij/execution/util/PathMappingTable.java @@ -88,6 +88,11 @@ final class PathMappingTable extends ListTableWithButtons extends BaseTableView implements ItemsProvider, Sel return this; } - public TableViewModel getTableViewModel() { + public TableViewModel getTableViewModel() { return getListTableModel(); } @@ -274,7 +274,9 @@ public class TableView extends BaseTableView implements ItemsProvider, Sel defaultEditorsByColumnClass.put(String.class, new UIDefaults.LazyValue() { @Override public Object createValue(UIDefaults table) { - return new DefaultCellEditor(GuiUtils.createUndoableTextField()); + DefaultCellEditor editor = new DefaultCellEditor(GuiUtils.createUndoableTextField()); + editor.setClickCountToStart(1); + return editor; } }); } diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/packaging/JavaFxArtifactPropertiesEditor.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/packaging/JavaFxArtifactPropertiesEditor.java index 0006db9918c7..e4a7b47b673c 100644 --- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/packaging/JavaFxArtifactPropertiesEditor.java +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/packaging/JavaFxArtifactPropertiesEditor.java @@ -23,7 +23,6 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.util.Comparing; -import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; import com.intellij.packaging.artifacts.Artifact; import com.intellij.packaging.ui.ArtifactPropertiesEditor; @@ -316,6 +315,11 @@ public class JavaFxArtifactPropertiesEditor extends ArtifactPropertiesEditor { return new JavaFxManifestAttribute("", ""); } + @Override + protected boolean isEmpty(JavaFxManifestAttribute element) { + return element.getName().isEmpty() && element.getValue().isEmpty(); + } + @Override protected JavaFxManifestAttribute cloneElement(JavaFxManifestAttribute attribute) { return new JavaFxManifestAttribute(attribute.getName(), attribute.getValue()); diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ManageTemplateVariablesDialog.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ManageTemplateVariablesDialog.java index 3c3ed235454a..ebb8bd39997b 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ManageTemplateVariablesDialog.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ManageTemplateVariablesDialog.java @@ -206,6 +206,11 @@ public class ManageTemplateVariablesDialog extends DialogWrapper { return new TemplateVariable("", ""); } + @Override + protected boolean isEmpty(TemplateVariable element) { + return element.getName().isEmpty() && element.getValue().isEmpty(); + } + @Override protected TemplateVariable cloneElement(final TemplateVariable variable) { return variable.clone();