IDEA-255341 [new run config UI] Logs option adding and deleting is not saved
authorDmitry Avdeev <dmitry.avdeev@jetbrains.com>
Wed, 14 Apr 2021 08:44:27 +0000 (11:44 +0300)
committerintellij-monorepo-bot <intellij-monorepo-bot-no-reply@jetbrains.com>
Wed, 14 Apr 2021 08:45:31 +0000 (08:45 +0000)
fragment groups refactored

GitOrigin-RevId: 9b457a35b463fef1f6807683a7e36e0caefe5435

java/execution/impl/src/com/intellij/execution/application/JavaSettingsEditorBase.java
platform/execution-impl/src/com/intellij/diagnostic/logging/LogsFragment.java
platform/execution-impl/src/com/intellij/diagnostic/logging/LogsGroupFragment.java [new file with mode: 0644]
platform/platform-api/src/com/intellij/execution/ui/FragmentedSettingsBuilder.java
platform/platform-api/src/com/intellij/execution/ui/NestedGroupFragment.java

index d09852a9b946b85cb7b2cc0626eecaf5ba93a1a8..9d6ba4fac298c0222d5149b9fa034aec718345d5 100644 (file)
@@ -2,7 +2,7 @@
 package com.intellij.execution.application;
 
 import com.intellij.compiler.options.CompileStepBeforeRun;
-import com.intellij.diagnostic.logging.LogsFragment;
+import com.intellij.diagnostic.logging.LogsGroupFragment;
 import com.intellij.execution.ExecutionBundle;
 import com.intellij.execution.JavaRunConfigurationBase;
 import com.intellij.execution.JavaRunConfigurationExtensionManager;
@@ -65,7 +65,7 @@ public abstract class JavaSettingsEditorBase<T extends JavaRunConfigurationBase>
     fragments.add(moduleClasspath);
     customizeFragments(fragments, moduleClasspath, commonParameterFragments);
 
-    fragments.add(new LogsFragment<>());
+    fragments.add(new LogsGroupFragment<>());
     return fragments;
   }
 
index 9c150ada43d638d663653ef48b796c0be1992616..68b6838cf018ce99778c9057305d44823e469a2e 100644 (file)
@@ -6,14 +6,8 @@ import com.intellij.execution.ExecutionBundle;
 import com.intellij.execution.configurations.LogFileOptions;
 import com.intellij.execution.configurations.PredefinedLogFile;
 import com.intellij.execution.configurations.RunConfigurationBase;
-import com.intellij.execution.ui.NestedGroupFragment;
 import com.intellij.execution.ui.SettingsEditorFragment;
 import com.intellij.openapi.actionSystem.ActionToolbarPosition;
-import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
-import com.intellij.openapi.ui.LabeledComponent;
-import com.intellij.openapi.ui.TextComponentAccessor;
-import com.intellij.openapi.ui.TextFieldWithBrowseButton;
-import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.wm.IdeFocusManager;
 import com.intellij.ui.BooleanTableCellRenderer;
 import com.intellij.ui.TableUtil;
@@ -26,12 +20,13 @@ import com.intellij.util.ui.LocalPathCellEditor;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
+import javax.swing.*;
 import javax.swing.table.*;
 import java.awt.*;
 import java.util.List;
 import java.util.*;
 
-public final class LogsFragment<T extends RunConfigurationBase<?>> extends NestedGroupFragment<T> {
+public final class LogsFragment<T extends RunConfigurationBase<?>> extends SettingsEditorFragment<T, JComponent> {
   private final Map<LogFileOptions, PredefinedLogFile> myLog2Predefined = new HashMap<>();
   private final List<PredefinedLogFile> myUnresolvedPredefined = new SmartList<>();
   private final TableView<LogFileOptions> myFilesTable;
@@ -39,7 +34,7 @@ public final class LogsFragment<T extends RunConfigurationBase<?>> extends Neste
 
   public LogsFragment() {
     super("log.monitor",
-          DiagnosticBundle.message("log.monitor.fragment.name"), DiagnosticBundle.message("log.monitor.fragment.group"),
+          DiagnosticBundle.message("log.monitor.fragment.name"), null, null, null, null,
           t -> !t.getLogFiles().isEmpty());
     setActionHint(ExecutionBundle.message("the.ide.will.display.the.selected.logs.in.the.run.tool.window"));
 
@@ -127,7 +122,6 @@ public final class LogsFragment<T extends RunConfigurationBase<?>> extends Neste
 
   @Override
   protected void resetEditorFrom(@NotNull T configuration) {
-    super.resetEditorFrom(configuration);
     List<LogFileOptions> list = new ArrayList<>();
     final List<LogFileOptions> logFiles = configuration.getLogFiles();
     for (LogFileOptions setting : logFiles) {
@@ -154,7 +148,6 @@ public final class LogsFragment<T extends RunConfigurationBase<?>> extends Neste
 
   @Override
   protected void applyEditorTo(@NotNull T configuration) {
-    super.applyEditorTo(configuration);
     configuration.removeAllLogFiles();
     configuration.removeAllPredefinedLogFiles();
     if (!isSelected()) return;
@@ -182,40 +175,6 @@ public final class LogsFragment<T extends RunConfigurationBase<?>> extends Neste
     }
   }
 
-  @Override
-  protected List<SettingsEditorFragment<T, ?>> createChildren() {
-    TextFieldWithBrowseButton myOutputFile = new TextFieldWithBrowseButton();
-    myOutputFile.addBrowseFolderListener(ExecutionBundle.message("choose.file.to.save.console.output"),
-                                         ExecutionBundle.message("console.output.would.be.saved.to.the.specified.file"), null,
-                                         FileChooserDescriptorFactory.createSingleFileOrFolderDescriptor(),
-                                         TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT);
-    LabeledComponent<TextFieldWithBrowseButton> component =
-      LabeledComponent.create(myOutputFile, ExecutionBundle.message("save.output.console.to.file"), BorderLayout.WEST);
-    SettingsEditorFragment<T, LabeledComponent<TextFieldWithBrowseButton>> fragment =
-      new SettingsEditorFragment<>("logs.save.output", ExecutionBundle.message("save.output.console.to.file.option"), null, component,
-                                   (t, c) -> c.getComponent().setText(StringUtil.notNullize(t.getOutputFilePath())),
-                                   (t, c) -> {
-                                     t.setFileOutputPath(c.getComponent().getText());
-                                     t.setSaveOutputToFile(c.isVisible() && StringUtil.isNotEmpty(component.getComponent().getText()));
-                                   },
-                                   t -> t.isSaveOutputToFile());
-    fragment.setActionHint(ExecutionBundle.message("write.the.output.of.the.application.to.a.file.for.later.inspection"));
-    SettingsEditorFragment<T, ?> stdOut = SettingsEditorFragment
-      .createTag("logs.stdout", DiagnosticBundle.message("log.monitor.fragment.stdout"), null, t -> t.isShowConsoleOnStdOut(),
-                 (t, value) -> t.setShowConsoleOnStdOut(value));
-    stdOut.setActionHint(ExecutionBundle.message("activate.the.console.when.the.application.writes.to.the.standard.output.stream"));
-    SettingsEditorFragment<T, ?> stdErr = SettingsEditorFragment
-      .createTag("logs.stderr", DiagnosticBundle.message("log.monitor.fragment.stderr"), null, t -> t.isShowConsoleOnStdErr(),
-                 (t, value) -> t.setShowConsoleOnStdErr(value));
-    stdErr.setActionHint(ExecutionBundle.message("activate.the.console.when.the.application.writes.to.the.standard.error.stream"));
-    return Arrays.asList(fragment, stdOut, stdErr);
-  }
-
-  @Override
-  public String getChildrenGroupName() {
-    return DiagnosticBundle.message("log.monitor.fragment.settings");
-  }
-
   private class TabNameColumnInfo extends ColumnInfo<LogFileOptions, String> {
     TabNameColumnInfo() {
       super(DiagnosticBundle.message("log.monitor.tab.name.column"));
diff --git a/platform/execution-impl/src/com/intellij/diagnostic/logging/LogsGroupFragment.java b/platform/execution-impl/src/com/intellij/diagnostic/logging/LogsGroupFragment.java
new file mode 100644 (file)
index 0000000..6186b3f
--- /dev/null
@@ -0,0 +1,61 @@
+// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+package com.intellij.diagnostic.logging;
+
+import com.intellij.diagnostic.DiagnosticBundle;
+import com.intellij.execution.ExecutionBundle;
+import com.intellij.execution.configurations.RunConfigurationBase;
+import com.intellij.execution.ui.NestedGroupFragment;
+import com.intellij.execution.ui.SettingsEditorFragment;
+import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
+import com.intellij.openapi.ui.LabeledComponent;
+import com.intellij.openapi.ui.TextComponentAccessor;
+import com.intellij.openapi.ui.TextFieldWithBrowseButton;
+import com.intellij.openapi.util.text.StringUtil;
+
+import java.awt.*;
+import java.util.Arrays;
+import java.util.List;
+
+public class LogsGroupFragment<T extends RunConfigurationBase<?>> extends NestedGroupFragment<T> {
+
+  public LogsGroupFragment() {
+    super("log",
+          DiagnosticBundle.message("log.monitor.fragment.name"), DiagnosticBundle.message("log.monitor.fragment.group"),
+          t -> false);
+    setActionHint(ExecutionBundle.message("the.ide.will.display.the.selected.logs.in.the.run.tool.window"));
+  }
+
+    @Override
+  protected List<SettingsEditorFragment<T, ?>> createChildren() {
+    TextFieldWithBrowseButton myOutputFile = new TextFieldWithBrowseButton();
+    myOutputFile.addBrowseFolderListener(ExecutionBundle.message("choose.file.to.save.console.output"),
+                                         ExecutionBundle.message("console.output.would.be.saved.to.the.specified.file"), null,
+                                         FileChooserDescriptorFactory.createSingleFileOrFolderDescriptor(),
+                                         TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT);
+    LabeledComponent<TextFieldWithBrowseButton> component =
+      LabeledComponent.create(myOutputFile, ExecutionBundle.message("save.output.console.to.file"), BorderLayout.WEST);
+    SettingsEditorFragment<T, LabeledComponent<TextFieldWithBrowseButton>> fragment =
+      new SettingsEditorFragment<>("logs.save.output", ExecutionBundle.message("save.output.console.to.file.option"), null, component,
+                                   (t, c) -> c.getComponent().setText(StringUtil.notNullize(t.getOutputFilePath())),
+                                   (t, c) -> {
+                                     t.setFileOutputPath(c.getComponent().getText());
+                                     t.setSaveOutputToFile(c.isVisible() && StringUtil.isNotEmpty(component.getComponent().getText()));
+                                   },
+                                   t -> t.isSaveOutputToFile());
+    fragment.setActionHint(ExecutionBundle.message("write.the.output.of.the.application.to.a.file.for.later.inspection"));
+    SettingsEditorFragment<T, ?> stdOut = SettingsEditorFragment
+      .createTag("logs.stdout", DiagnosticBundle.message("log.monitor.fragment.stdout"), null, t -> t.isShowConsoleOnStdOut(),
+                 (t, value) -> t.setShowConsoleOnStdOut(value));
+    stdOut.setActionHint(ExecutionBundle.message("activate.the.console.when.the.application.writes.to.the.standard.output.stream"));
+    SettingsEditorFragment<T, ?> stdErr = SettingsEditorFragment
+      .createTag("logs.stderr", DiagnosticBundle.message("log.monitor.fragment.stderr"), null, t -> t.isShowConsoleOnStdErr(),
+                 (t, value) -> t.setShowConsoleOnStdErr(value));
+    stdErr.setActionHint(ExecutionBundle.message("activate.the.console.when.the.application.writes.to.the.standard.error.stream"));
+    return Arrays.asList(new LogsFragment<>(), fragment, stdOut, stdErr);
+  }
+
+  @Override
+  public String getChildrenGroupName() {
+    return DiagnosticBundle.message("log.monitor.fragment.settings");
+  }
+}
index 843216a4a19235e8807a4e8d09da3ef65cf00fb5..cd1a56aa3e47ee99bf4f9a3c42f0c757455f5f1a 100644 (file)
@@ -31,6 +31,7 @@ import com.intellij.util.ui.JBUI;
 import com.intellij.util.ui.UIUtil;
 import com.intellij.util.ui.WrapLayout;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
 import java.awt.*;
@@ -38,7 +39,7 @@ import java.util.List;
 import java.util.*;
 import java.util.stream.Collectors;
 
-public class FragmentedSettingsBuilder<Settings> implements CompositeSettingsBuilder<Settings>, Disposable {
+public class FragmentedSettingsBuilder<Settings extends FragmentedSettings> implements CompositeSettingsBuilder<Settings>, Disposable {
 
   static final int TOP_INSET = 5;
   static final int GROUP_INSET = 20;
@@ -63,13 +64,13 @@ public class FragmentedSettingsBuilder<Settings> implements CompositeSettingsBui
   private final GridBagConstraints myConstraints =
     new GridBagConstraints(0, 0, 1, 1, 1, 0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, JBUI.insetsTop(TOP_INSET), 0, 0);
   private final Collection<? extends SettingsEditorFragment<Settings, ?>> myFragments;
-  private final SettingsEditorFragment<Settings, ?> myMain;
+  private final @Nullable NestedGroupFragment<Settings> myMain;
   private int myGroupInset;
   private DropDownLink<String> myLinkLabel;
   private String myConfigId; // for FUS
 
   FragmentedSettingsBuilder(Collection<? extends SettingsEditorFragment<Settings, ?>> fragments,
-                            SettingsEditorFragment<Settings, ?> main, @NotNull Disposable parentDisposable) {
+                            @Nullable NestedGroupFragment<Settings> main, @NotNull Disposable parentDisposable) {
     myFragments = fragments;
     myMain = main;
     Disposer.register(parentDisposable, this);
@@ -254,16 +255,17 @@ public class FragmentedSettingsBuilder<Settings> implements CompositeSettingsBui
         actionGroup.add(customGroup);
         continue;
       }
-      ToggleFragmentAction action = new ToggleFragmentAction(fragment, lastSelected);
-      ShortcutSet shortcutSet = ActionUtil.getMnemonicAsShortcut(action);
-      if (shortcutSet != null) {
-        action.registerCustomShortcutSet(shortcutSet, null);
-      }
-      actionGroup.add(action);
       List<SettingsEditorFragment<Settings, ?>> children = fragment.getChildren();
-      if (!children.isEmpty()) {
+      if (children.isEmpty()) {
+        ToggleFragmentAction action = new ToggleFragmentAction(fragment, lastSelected);
+        ShortcutSet shortcutSet = ActionUtil.getMnemonicAsShortcut(action);
+        if (shortcutSet != null) {
+          action.registerCustomShortcutSet(shortcutSet, null);
+        }
+        actionGroup.add(action);
+      }
+      else {
         DefaultActionGroup childGroup = buildGroup(children, lastSelected);
-        childGroup.setPopup(true);
         childGroup.getTemplatePresentation().setText(fragment.getChildrenGroupName());
         actionGroup.add(childGroup);
       }
@@ -272,12 +274,7 @@ public class FragmentedSettingsBuilder<Settings> implements CompositeSettingsBui
   }
 
   private DefaultActionGroup buildGroup(Ref<? super JComponent> lastSelected) {
-    DefaultActionGroup group = buildGroup(ContainerUtil.filter(myFragments, fragment -> fragment.getName() != null), lastSelected);
-    if (myMain != null) {
-      group.add(Separator.create(), Constraints.FIRST);
-      group.add(new ToggleFragmentAction(myMain, lastSelected), Constraints.FIRST);
-    }
-    return group;
+    return buildGroup(ContainerUtil.filter(myFragments, fragment -> fragment.getName() != null), lastSelected);
   }
 
   private List<SettingsEditorFragment<Settings, ?>> restoreGroups(List<? extends SettingsEditorFragment<Settings, ?>> fragments) {
index d1beb6bbfac2cc81c3363fc14d13dda806996651..00a78306b7261d2a0c38de2ca758347de1f54024 100644 (file)
@@ -53,6 +53,11 @@ public abstract class NestedGroupFragment<S extends FragmentedSettings> extends
     updateVisibility();
   }
 
+  @Override
+  public boolean isSelected() {
+    return ContainerUtil.exists(getChildren(), fragment -> fragment.isSelected());
+  }
+
   @Override
   public boolean isInitiallyVisible(S s) {
     return super.isInitiallyVisible(s) || ContainerUtil.exists(getChildren(), fragment -> fragment.isInitiallyVisible(s));