- Provide setting for starting directory (IDEA-125383)
authorDmitry Trofimov <dmitry.trofimov@jetbrains.com>
Thu, 20 Oct 2016 19:41:02 +0000 (21:41 +0200)
committerDmitry Trofimov <dmitry.trofimov@jetbrains.com>
Thu, 20 Oct 2016 19:41:02 +0000 (21:41 +0200)
- Split settings into project and application parts (IDEA-157148)
- Respect changes of the default system shell (IDEA-147227)

plugins/terminal/src/org/jetbrains/plugins/terminal/LocalTerminalDirectRunner.java
plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalOptionsConfigurable.java
plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalOptionsProvider.java
plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalProjectOptionsProvider.java [new file with mode: 0644]
plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalSettingsPanel.form
plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalSettingsPanel.java

index 1d10271353da354cc3b77ea478509db55e43d8fb..f426ccc4d1a1fe506ed0fd049143ebac7150fd5f 100644 (file)
@@ -24,10 +24,8 @@ import com.intellij.execution.process.ProcessHandler;
 import com.intellij.execution.process.ProcessWaitFor;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.roots.ProjectRootManager;
 import com.intellij.openapi.util.SystemInfo;
 import com.intellij.openapi.vfs.CharsetToolkit;
-import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.util.ArrayUtil;
 import com.intellij.util.concurrency.AppExecutorUtil;
 import com.intellij.util.containers.HashMap;
@@ -129,24 +127,13 @@ public class LocalTerminalDirectRunner extends AbstractTerminalRunner<PtyProcess
     }
 
     try {
-      return PtyProcess.exec(command, envs, directory != null ? directory : currentProjectFolder());
+      return PtyProcess.exec(command, envs, directory != null ? directory : TerminalProjectOptionsProvider.getInstance(myProject).getStartingDirectory());
     }
     catch (IOException e) {
       throw new ExecutionException(e);
     }
   }
 
-  private String currentProjectFolder() {
-    final ProjectRootManager projectRootManager = ProjectRootManager.getInstance(myProject);
-
-    final VirtualFile[] roots = projectRootManager.getContentRoots();
-    if (roots.length == 1) {
-      roots[0].getCanonicalPath();
-    }
-    final VirtualFile baseDir = myProject.getBaseDir();
-    return baseDir == null ? null : baseDir.getCanonicalPath();
-  }
-
   @Override
   protected ProcessHandler createProcessHandler(final PtyProcess process) {
     return new PtyProcessHandler(process, getShellPath());
@@ -176,7 +163,7 @@ public class LocalTerminalDirectRunner extends AbstractTerminalRunner<PtyProcess
   }
 
   private String getShellPath() {
-    return TerminalOptionsProvider.getInstance().getShellPath();
+    return TerminalProjectOptionsProvider.getInstance(myProject).getShellPath();
   }
 
   @NotNull
index 3e799eff36e690bfa5900cecae19b8cfebb0d9fb..db7846fa7c60f7022eceffeda0f1845a3ccd0ae8 100644 (file)
@@ -19,6 +19,7 @@ import com.intellij.openapi.Disposable;
 import com.intellij.openapi.options.Configurable;
 import com.intellij.openapi.options.ConfigurationException;
 import com.intellij.openapi.options.SearchableConfigurable;
+import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Disposer;
 import org.jetbrains.annotations.Nls;
 import org.jetbrains.annotations.NotNull;
@@ -33,9 +34,11 @@ public class TerminalOptionsConfigurable implements SearchableConfigurable, Conf
 
   private TerminalSettingsPanel myPanel;
   private final TerminalOptionsProvider myOptionsProvider;
+  private final TerminalProjectOptionsProvider myProjectOptionsProvider;
 
-  public TerminalOptionsConfigurable() {
+  public TerminalOptionsConfigurable(@NotNull Project project) {
     myOptionsProvider = TerminalOptionsProvider.getInstance();
+    myProjectOptionsProvider = TerminalProjectOptionsProvider.getInstance(project);
   }
 
   @NotNull
@@ -58,7 +61,7 @@ public class TerminalOptionsConfigurable implements SearchableConfigurable, Conf
   @Override
   public JComponent createComponent() {
     myPanel = new TerminalSettingsPanel();
-    return myPanel.createPanel(myOptionsProvider);
+    return myPanel.createPanel(myOptionsProvider, myProjectOptionsProvider);
   }
 
   @Override
index 01466b72610a82f71879b4234a8053a36bc923a1..e43e7d0346762700828ba5d638015e9e3d847cb9 100644 (file)
@@ -19,9 +19,6 @@ import com.intellij.openapi.components.PersistentStateComponent;
 import com.intellij.openapi.components.ServiceManager;
 import com.intellij.openapi.components.State;
 import com.intellij.openapi.components.Storage;
-import com.intellij.openapi.util.SystemInfo;
-
-import java.io.File;
 
 /**
  * @author traff
@@ -44,7 +41,6 @@ public class TerminalOptionsProvider implements PersistentStateComponent<Termina
 
   @Override
   public void loadState(State state) {
-    myState.myShellPath = state.myShellPath;
     myState.myCloseSessionOnLogout = state.myCloseSessionOnLogout;
     myState.myReportMouse = state.myReportMouse;
     myState.mySoundBell = state.mySoundBell;
@@ -88,7 +84,6 @@ public class TerminalOptionsProvider implements PersistentStateComponent<Termina
   }
 
   public static class State {
-    public String myShellPath = getDefaultShellPath();
     public String myTabName = "Local";
     public boolean myCloseSessionOnLogout = true;
     public boolean myReportMouse = true;
@@ -99,33 +94,6 @@ public class TerminalOptionsProvider implements PersistentStateComponent<Termina
     public boolean myShellIntegration = true;
   }
 
-  public String getShellPath() {
-    return myState.myShellPath;
-  }
-
-  private static String getDefaultShellPath() {
-    String shell = System.getenv("SHELL");
-
-    if (shell != null && new File(shell).canExecute()) {
-      return shell;
-    }
-
-    if (SystemInfo.isUnix) {
-      if (new File("/bin/bash").exists()) {
-        return "/bin/bash";
-      } else {
-        return "/bin/sh";
-      }
-    }
-    else {
-      return "cmd.exe";
-    }
-  }
-
-  public void setShellPath(String shellPath) {
-    myState.myShellPath = shellPath;
-  }
-
   public void setTabName(String tabName) {
     myState.myTabName = tabName;
   }
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalProjectOptionsProvider.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalProjectOptionsProvider.java
new file mode 100644 (file)
index 0000000..6b94436
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2000-2016 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 org.jetbrains.plugins.terminal;
+
+import com.intellij.openapi.components.PersistentStateComponent;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.components.State;
+import com.intellij.openapi.components.Storage;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+
+/**
+ * @author traff
+ */
+@State(
+  name = "TerminalOptionsProvider",
+  storages = @Storage("terminal.xml")
+)
+public class TerminalProjectOptionsProvider implements PersistentStateComponent<TerminalProjectOptionsProvider.State> {
+  private static final Logger LOG = Logger.getInstance(TerminalProjectOptionsProvider.class);
+
+  private State myState = new State();
+  private final Project myProject;
+
+  public TerminalProjectOptionsProvider(Project project) {myProject = project;}
+
+
+  public static TerminalProjectOptionsProvider getInstance(@NotNull Project project) {
+    return ServiceManager.getService(project, TerminalProjectOptionsProvider.class);
+  }
+
+  @Override
+  public State getState() {
+    return myState;
+  }
+
+  @Override
+  public void loadState(State state) {
+    setShellPath(state.myShellPath);
+    myState.myStartingDirectory = state.myStartingDirectory;
+  }
+
+
+  public static class State {
+    public String myShellPath = null;
+    public String myStartingDirectory = null;
+  }
+
+  public String getShellPath() {
+    if (myState.myShellPath != null) {
+      return myState.myShellPath;
+    } else {
+      return getDefaultShellPath();
+    }
+  }
+
+
+  public void setShellPath(String shellPath) {
+    if (isShellPathDefault(shellPath) || StringUtil.isEmpty(shellPath)) {
+      myState.myShellPath = null;
+    } else {
+      myState.myShellPath = shellPath;
+    }
+  }
+
+
+  public void setStartingDirectory(String startingDirectory) {
+    if (isStartingDirectoryDefault(startingDirectory) || StringUtil.isEmpty(startingDirectory)) {
+      myState.myStartingDirectory = null;
+    } else {
+      myState.myStartingDirectory = startingDirectory;
+    }
+  }
+
+  public boolean isShellPathDefault(String shellPath) {
+    return StringUtil.equals(shellPath, getDefaultShellPath());
+  }
+
+  public boolean isStartingDirectoryDefault(String startingDirectory) {
+    return StringUtil.equals(startingDirectory, getDefaultStartingDirectory());
+  }
+
+  public String getStartingDirectory() {
+    if (myState.myStartingDirectory != null) {
+      return myState.myStartingDirectory;
+    }
+    else {
+      return getDefaultStartingDirectory();
+    }
+  }
+
+
+  private static String getDefaultShellPath() {
+    String shell = System.getenv("SHELL");
+
+    if (shell != null && new File(shell).canExecute()) {
+      return shell;
+    }
+
+    if (SystemInfo.isUnix) {
+      if (new File("/bin/bash").exists()) {
+        return "/bin/bash";
+      }
+      else {
+        return "/bin/sh";
+      }
+    }
+    else {
+      return "cmd.exe";
+    }
+  }
+
+  public String getDefaultStartingDirectory() {
+    String directory = null;
+    for (LocalTerminalCustomizer customizer : LocalTerminalCustomizer.EP_NAME.getExtensions()) {
+      try {
+
+        if (directory == null) {
+          directory = customizer.getDefaultFolder();
+        }
+      }
+      catch (Exception e) {
+        LOG.error("Exception during getting default folder", e);
+      }
+    }
+
+    return currentProjectFolder();
+  }
+
+
+  private String currentProjectFolder() {
+    final ProjectRootManager projectRootManager = ProjectRootManager.getInstance(myProject);
+
+    final VirtualFile[] roots = projectRootManager.getContentRoots();
+    if (roots.length == 1) {
+      roots[0].getCanonicalPath();
+    }
+    final VirtualFile baseDir = myProject.getBaseDir();
+    return baseDir == null ? null : baseDir.getCanonicalPath();
+  }
+}
+
index af3c82b03badab895416cefdec975a5dbcd9b5bb..f8963c843dd92e55f8fad2ca0a2e9857049a3c1e 100644 (file)
@@ -3,12 +3,12 @@
   <grid id="27dc6" binding="myWholePanel" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
     <margin top="0" left="0" bottom="0" right="0"/>
     <constraints>
-      <xy x="20" y="20" width="500" height="400"/>
+      <xy x="20" y="20" width="500" height="482"/>
     </constraints>
     <properties/>
     <border type="none"/>
     <children>
-      <grid id="8f9b9" layout-manager="GridLayoutManager" row-count="8" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+      <grid id="8f9b9" layout-manager="GridLayoutManager" row-count="9" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
         <margin top="0" left="0" bottom="0" right="0"/>
         <constraints>
           <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
         </clientProperties>
         <border type="none"/>
         <children>
-          <grid id="57ec0" layout-manager="GridLayoutManager" row-count="2" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+          <vspacer id="d777c">
+            <constraints>
+              <grid row="2" column="0" row-span="7" col-span="4" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+            </constraints>
+          </vspacer>
+          <grid id="871ca" binding="myProjectSettingsPanel" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
             <margin top="0" left="0" bottom="0" right="0"/>
             <constraints>
               <grid row="0" column="0" row-span="1" col-span="4" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
                   <text value="Shell path"/>
                 </properties>
               </component>
-              <component id="f633a" class="javax.swing.JLabel">
+              <component id="aad87" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="myShellPathField">
+                <constraints>
+                  <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+                </constraints>
+                <properties/>
+              </component>
+              <component id="40fca" class="javax.swing.JLabel">
                 <constraints>
                   <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
                 </constraints>
                 <properties>
                   <horizontalTextPosition value="2"/>
-                  <text value="Tab name"/>
+                  <text value="Start directory"/>
                 </properties>
               </component>
-              <component id="5495b" class="javax.swing.JTextField" binding="myTabNameTextField">
+              <component id="16cd7" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="myStartDirectoryField">
                 <constraints>
-                  <grid row="1" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
-                    <preferred-size width="150" height="-1"/>
-                  </grid>
-                </constraints>
-                <properties/>
-              </component>
-              <component id="aad87" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="myShellPathField">
-                <constraints>
-                  <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+                  <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
                 </constraints>
                 <properties/>
               </component>
             </children>
           </grid>
-          <vspacer id="d777c">
-            <constraints>
-              <grid row="7" column="0" row-span="1" col-span="4" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
-            </constraints>
-          </vspacer>
-          <grid id="caa1d" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+          <grid id="5c27f" binding="myGlobalSettingsPanel" layout-manager="GridLayoutManager" row-count="8" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
             <margin top="0" left="0" bottom="0" right="0"/>
             <constraints>
               <grid row="1" column="0" row-span="1" col-span="4" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
             <properties/>
             <border type="none"/>
             <children>
-              <component id="f974" class="com.intellij.ui.components.JBCheckBox" binding="myCloseSessionCheckBox">
-                <constraints>
-                  <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
-                </constraints>
-                <properties>
-                  <text value="Close session when it ends"/>
-                </properties>
-              </component>
-              <hspacer id="4d085">
+              <grid id="57ec0" layout-manager="GridLayoutManager" row-count="1" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+                <margin top="0" left="0" bottom="0" right="0"/>
                 <constraints>
-                  <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+                  <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
                 </constraints>
-              </hspacer>
+                <properties/>
+                <border type="none"/>
+                <children>
+                  <component id="f633a" class="javax.swing.JLabel">
+                    <constraints>
+                      <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                    </constraints>
+                    <properties>
+                      <horizontalTextPosition value="2"/>
+                      <text value="Tab name"/>
+                    </properties>
+                  </component>
+                  <component id="5495b" class="javax.swing.JTextField" binding="myTabNameTextField">
+                    <constraints>
+                      <grid row="0" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+                        <preferred-size width="150" height="-1"/>
+                      </grid>
+                    </constraints>
+                    <properties/>
+                  </component>
+                </children>
+              </grid>
               <grid id="b4260" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
                 <margin top="0" left="0" bottom="0" right="0"/>
                 <constraints>
-                  <grid row="1" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+                  <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
                 </constraints>
                 <properties/>
                 <border type="none"/>
                   </hspacer>
                 </children>
               </grid>
-            </children>
-          </grid>
-          <grid id="efc62" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-            <margin top="0" left="0" bottom="0" right="0"/>
-            <constraints>
-              <grid row="2" column="0" row-span="1" col-span="4" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
-            </constraints>
-            <properties/>
-            <border type="none"/>
-            <children>
-              <component id="e2773" class="com.intellij.ui.components.JBCheckBox" binding="myMouseReportCheckBox">
-                <constraints>
-                  <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
-                </constraints>
-                <properties>
-                  <text value="Mouse reporting"/>
-                </properties>
-              </component>
-              <hspacer id="2f4aa">
-                <constraints>
-                  <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
-                </constraints>
-              </hspacer>
-            </children>
-          </grid>
-          <grid id="e134" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-            <margin top="0" left="0" bottom="0" right="0"/>
-            <constraints>
-              <grid row="3" column="0" row-span="1" col-span="4" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
-            </constraints>
-            <properties/>
-            <border type="none"/>
-            <children>
-              <component id="f1844" class="com.intellij.ui.components.JBCheckBox" binding="myCopyOnSelectionCheckBox">
-                <constraints>
-                  <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
-                </constraints>
-                <properties>
-                  <text value="Copy to clipboard on selection"/>
-                </properties>
-              </component>
-              <hspacer id="f4740">
-                <constraints>
-                  <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
-                </constraints>
-              </hspacer>
-            </children>
-          </grid>
-          <grid id="5aa62" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-            <margin top="0" left="0" bottom="0" right="0"/>
-            <constraints>
-              <grid row="4" column="0" row-span="1" col-span="4" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
-            </constraints>
-            <properties/>
-            <border type="none"/>
-            <children>
-              <component id="8a427" class="com.intellij.ui.components.JBCheckBox" binding="myPasteOnMiddleButtonCheckBox">
+              <grid id="caa1d" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+                <margin top="0" left="0" bottom="0" right="0"/>
                 <constraints>
-                  <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
+                  <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
                 </constraints>
-                <properties>
-                  <text value="Paste on middle mouse button click"/>
-                </properties>
-              </component>
-              <hspacer id="cfc3e">
+                <properties/>
+                <border type="none"/>
+                <children>
+                  <component id="f974" class="com.intellij.ui.components.JBCheckBox" binding="myCloseSessionCheckBox">
+                    <constraints>
+                      <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
+                    </constraints>
+                    <properties>
+                      <text value="Close session when it ends"/>
+                    </properties>
+                  </component>
+                  <hspacer id="4d085">
+                    <constraints>
+                      <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+                    </constraints>
+                  </hspacer>
+                </children>
+              </grid>
+              <grid id="efc62" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+                <margin top="0" left="0" bottom="0" right="0"/>
                 <constraints>
-                  <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+                  <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
                 </constraints>
-              </hspacer>
-            </children>
-          </grid>
-          <grid id="74977" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-            <margin top="0" left="0" bottom="0" right="0"/>
-            <constraints>
-              <grid row="5" column="0" row-span="1" col-span="4" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
-            </constraints>
-            <properties/>
-            <border type="none"/>
-            <children>
-              <component id="226ed" class="com.intellij.ui.components.JBCheckBox" binding="myOverrideIdeShortcuts">
+                <properties/>
+                <border type="none"/>
+                <children>
+                  <component id="e2773" class="com.intellij.ui.components.JBCheckBox" binding="myMouseReportCheckBox">
+                    <constraints>
+                      <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
+                    </constraints>
+                    <properties>
+                      <text value="Mouse reporting"/>
+                    </properties>
+                  </component>
+                  <hspacer id="2f4aa">
+                    <constraints>
+                      <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+                    </constraints>
+                  </hspacer>
+                </children>
+              </grid>
+              <grid id="e134" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+                <margin top="0" left="0" bottom="0" right="0"/>
                 <constraints>
-                  <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
+                  <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
                 </constraints>
-                <properties>
-                  <text value="Override IDE shortcuts"/>
-                </properties>
-              </component>
-              <hspacer id="e2d4a">
+                <properties/>
+                <border type="none"/>
+                <children>
+                  <component id="f1844" class="com.intellij.ui.components.JBCheckBox" binding="myCopyOnSelectionCheckBox">
+                    <constraints>
+                      <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
+                    </constraints>
+                    <properties>
+                      <text value="Copy to clipboard on selection"/>
+                    </properties>
+                  </component>
+                  <hspacer id="f4740">
+                    <constraints>
+                      <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+                    </constraints>
+                  </hspacer>
+                </children>
+              </grid>
+              <grid id="5aa62" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+                <margin top="0" left="0" bottom="0" right="0"/>
                 <constraints>
-                  <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+                  <grid row="5" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
                 </constraints>
-              </hspacer>
-            </children>
-          </grid>
-          <grid id="bcf3e" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-            <margin top="0" left="0" bottom="0" right="0"/>
-            <constraints>
-              <grid row="6" column="0" row-span="1" col-span="4" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
-            </constraints>
-            <properties/>
-            <border type="none"/>
-            <children>
-              <component id="26610" class="com.intellij.ui.components.JBCheckBox" binding="myShellIntegration">
+                <properties/>
+                <border type="none"/>
+                <children>
+                  <component id="8a427" class="com.intellij.ui.components.JBCheckBox" binding="myPasteOnMiddleButtonCheckBox">
+                    <constraints>
+                      <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
+                    </constraints>
+                    <properties>
+                      <text value="Paste on middle mouse button click"/>
+                    </properties>
+                  </component>
+                  <hspacer id="cfc3e">
+                    <constraints>
+                      <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+                    </constraints>
+                  </hspacer>
+                </children>
+              </grid>
+              <grid id="74977" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+                <margin top="0" left="0" bottom="0" right="0"/>
                 <constraints>
-                  <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
+                  <grid row="6" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
                 </constraints>
-                <properties>
-                  <text value="Shell integration"/>
-                </properties>
-              </component>
-              <hspacer id="69672">
+                <properties/>
+                <border type="none"/>
+                <children>
+                  <component id="226ed" class="com.intellij.ui.components.JBCheckBox" binding="myOverrideIdeShortcuts">
+                    <constraints>
+                      <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
+                    </constraints>
+                    <properties>
+                      <text value="Override IDE shortcuts"/>
+                    </properties>
+                  </component>
+                  <hspacer id="e2d4a">
+                    <constraints>
+                      <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+                    </constraints>
+                  </hspacer>
+                </children>
+              </grid>
+              <grid id="bcf3e" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+                <margin top="0" left="0" bottom="0" right="0"/>
                 <constraints>
-                  <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+                  <grid row="7" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
                 </constraints>
-              </hspacer>
+                <properties/>
+                <border type="none"/>
+                <children>
+                  <component id="26610" class="com.intellij.ui.components.JBCheckBox" binding="myShellIntegration">
+                    <constraints>
+                      <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
+                    </constraints>
+                    <properties>
+                      <text value="Shell integration"/>
+                    </properties>
+                  </component>
+                  <hspacer id="69672">
+                    <constraints>
+                      <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+                    </constraints>
+                  </hspacer>
+                </children>
+              </grid>
             </children>
           </grid>
         </children>
index 66c0da8664de428aeb041e0d9223eff51de0b26e..1ae6c15aabb9b65034b05fc941614874f9480752 100644 (file)
@@ -19,10 +19,15 @@ import com.intellij.openapi.fileChooser.FileChooserDescriptor;
 import com.intellij.openapi.ui.TextComponentAccessor;
 import com.intellij.openapi.ui.TextFieldWithBrowseButton;
 import com.intellij.openapi.util.Comparing;
+import com.intellij.ui.DocumentAdapter;
+import com.intellij.ui.IdeBorderFactory;
 import com.intellij.ui.components.JBCheckBox;
 import org.jetbrains.annotations.NotNull;
 
 import javax.swing.*;
+import javax.swing.event.DocumentEvent;
+import java.awt.*;
+import java.util.Arrays;
 
 /**
  * @author traff
@@ -38,27 +43,61 @@ public class TerminalSettingsPanel {
   private JBCheckBox myCopyOnSelectionCheckBox;
   private JBCheckBox myOverrideIdeShortcuts;
   private JBCheckBox myShellIntegration;
+  private TextFieldWithBrowseButton myStartDirectoryField;
+  private JPanel myProjectSettingsPanel;
+  private JPanel myGlobalSettingsPanel;
   private TerminalOptionsProvider myOptionsProvider;
+  private TerminalProjectOptionsProvider myProjectOptionsProvider;
 
-  public JComponent createPanel(@NotNull TerminalOptionsProvider provider) {
+  public JComponent createPanel(@NotNull TerminalOptionsProvider provider, @NotNull TerminalProjectOptionsProvider projectOptionsProvider) {
     myOptionsProvider = provider;
+    myProjectOptionsProvider = projectOptionsProvider;
+
+    myProjectSettingsPanel.setBorder(IdeBorderFactory.createTitledBorder("Project settings"));
+    myGlobalSettingsPanel.setBorder(IdeBorderFactory.createTitledBorder("Application settings"));
 
     FileChooserDescriptor fileChooserDescriptor = new FileChooserDescriptor(true, false, false, false, false, false);
 
     myShellPathField.addBrowseFolderListener(
       "",
-      "Shell Executable Path",
+      "Shell executable path",
+      null,
+      fileChooserDescriptor,
+      TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT);
+
+    fileChooserDescriptor = new FileChooserDescriptor(false, true, false, false, false, false);
+
+    myStartDirectoryField.addBrowseFolderListener(
+      "",
+      "Starting directory",
       null,
       fileChooserDescriptor,
-      TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT,
-      false
-    );
+      TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT);
+
+    myShellPathField.getTextField().getDocument().addDocumentListener(new DocumentAdapter() {
+      @Override
+      protected void textChanged(DocumentEvent e) {
+        myShellPathField
+          .getTextField().setForeground(myProjectOptionsProvider.isShellPathDefault(myShellPathField.getText()) ?
+                                        getDefaultValueColor() : getChangedValueColor());
+      }
+    });
+
+    myStartDirectoryField.getTextField().getDocument().addDocumentListener(new DocumentAdapter() {
+      @Override
+      protected void textChanged(DocumentEvent e) {
+        myStartDirectoryField
+          .getTextField().setForeground(myProjectOptionsProvider.isStartingDirectoryDefault(myStartDirectoryField.getText()) ?
+                                        getDefaultValueColor() : getChangedValueColor());
+      }
+    });
 
     return myWholePanel;
   }
 
   public boolean isModified() {
-    return !Comparing.equal(myShellPathField.getText(), myOptionsProvider.getShellPath())
+    return !Comparing.equal(myShellPathField.getText(), myProjectOptionsProvider.getShellPath())
+           || !Comparing.equal(myStartDirectoryField.getText(), myProjectOptionsProvider.getStartingDirectory())
            || !Comparing.equal(myTabNameTextField.getText(), myOptionsProvider.getTabName())
            || (myCloseSessionCheckBox.isSelected() != myOptionsProvider.closeSessionOnLogout())
            || (myMouseReportCheckBox.isSelected() != myOptionsProvider.enableMouseReporting())
@@ -71,7 +110,8 @@ public class TerminalSettingsPanel {
   }
 
   public void apply() {
-    myOptionsProvider.setShellPath(myShellPathField.getText());
+    myProjectOptionsProvider.setShellPath(myShellPathField.getText());
+    myProjectOptionsProvider.setStartingDirectory(myStartDirectoryField.getText());
     myOptionsProvider.setTabName(myTabNameTextField.getText());
     myOptionsProvider.setCloseSessionOnLogout(myCloseSessionCheckBox.isSelected());
     myOptionsProvider.setReportMouse(myMouseReportCheckBox.isSelected());
@@ -83,7 +123,8 @@ public class TerminalSettingsPanel {
   }
 
   public void reset() {
-    myShellPathField.setText(myOptionsProvider.getShellPath());
+    myShellPathField.setText(myProjectOptionsProvider.getShellPath());
+    myStartDirectoryField.setText(myProjectOptionsProvider.getStartingDirectory());
     myTabNameTextField.setText(myOptionsProvider.getTabName());
     myCloseSessionCheckBox.setSelected(myOptionsProvider.closeSessionOnLogout());
     myMouseReportCheckBox.setSelected(myOptionsProvider.enableMouseReporting());
@@ -93,4 +134,26 @@ public class TerminalSettingsPanel {
     myOverrideIdeShortcuts.setSelected(myOptionsProvider.overrideIdeShortcuts());
     myShellIntegration.setSelected(myOptionsProvider.shellIntegration());
   }
+
+  public Color getDefaultValueColor() {
+    return findColorByKey("TextField.inactiveForeground", "nimbusDisabledText");
+  }
+
+  @NotNull
+  private static Color findColorByKey(String... colorKeys) {
+    Color c = null;
+    for (String key : colorKeys) {
+      c = UIManager.getColor(key);
+      if (c != null) {
+        break;
+      }
+    }
+
+    assert c != null : "Can't find color for keys " + Arrays.toString(colorKeys);
+    return c;
+  }
+
+  public Color getChangedValueColor() {
+    return findColorByKey("TextField.foreground");
+  }
 }