[Mercurial] Better HgInit: provide option to create repository for the whole project.
authorKirill Likhodedov <kirill.likhodedov@jetbrains.com>
Fri, 18 Jun 2010 11:54:29 +0000 (15:54 +0400)
committerKirill Likhodedov <kirill.likhodedov@jetbrains.com>
Fri, 18 Jun 2010 11:54:29 +0000 (15:54 +0400)
plugins/hg4idea/resources/org/zmlx/hg4idea/HgVcsMessages.properties
plugins/hg4idea/src/org/zmlx/hg4idea/action/HgInit.java
plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgInitDialog.form [moved from plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgInitParentDialog.form with 57% similarity]
plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgInitDialog.java [new file with mode: 0644]

index 96db4c09061dcf5be5ac26a869dfa5e7d600e399..14fb6f21925b5c70b2fe1edce8f2001e9a9140a3 100644 (file)
@@ -21,10 +21,14 @@ hg4idea.error=Error
 hg4idea.revert=Revert
 hg4idea.commit=Commit
 
+hg4idea.init.dialog.title=Create Mercurial repository
+hg4idea.init.dialog.incorrect.path=The specified path is incorrect
+hg4idea.init.dialog.option.create.repository.for.whole.project=&Create repository for the whole project
+hg4idea.init.dialog.option.select.folder=&Select where to create repository
 hg4idea.init.destination.directory.description=Select directory where the new Mercurial repository will be created.
 hg4idea.init.destination.directory.title=Select directory for hg init
 hg4idea.init.this.is.hg.root=The selected folder {0} is already a Mercurial root
-hg4idea.init.already.under.hg.description=<html>The selected directory <b><code>{0}</code></b> is already under Mercurial: <b><code>{1}</code></b><br/>Would you like to create new repository in the selected folder or use the parent one?</html>
+hg4idea.init.already.under.hg.description=<html>The selected directory <b><code>{0}</code></b> is already under Mercurial: <b><code>{1}</code></b><br/>Would you like to create new repository in the selected folder or use the parent one?</html>
 hg4idea.init.already.under.hg.title=This directory is already under hg
 hg4idea.init.already.under.hg.dialog.title=Directory is under hg
 hg4idea.init.already.under.hg.option.create.project.at.parent=Use parent repository and create IDEA project for it.
index d5af79f433015cf28380db5d6d002104c7e5a7e3..8f3d2a7521e7c1d6533141b36211e96541d50e0b 100644 (file)
@@ -5,9 +5,6 @@ import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.actionSystem.PlatformDataKeys;
 import com.intellij.openapi.actionSystem.Presentation;
 import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.fileChooser.FileChooser;
-import com.intellij.openapi.fileChooser.FileChooserDescriptor;
-import com.intellij.openapi.options.ConfigurationException;
 import com.intellij.openapi.project.DumbAwareAction;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.vcs.ProjectLevelVcsManager;
@@ -15,9 +12,9 @@ import com.intellij.openapi.vcs.VcsDirectoryMapping;
 import com.intellij.openapi.vfs.VirtualFile;
 import org.zmlx.hg4idea.HgUtil;
 import org.zmlx.hg4idea.HgVcs;
-import org.zmlx.hg4idea.HgVcsMessages;
 import org.zmlx.hg4idea.command.HgInitCommand;
-import org.zmlx.hg4idea.ui.HgInitParentDialog;
+import org.zmlx.hg4idea.ui.HgInitAlreadyUnderHgDialog;
+import org.zmlx.hg4idea.ui.HgInitDialog;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -41,48 +38,43 @@ public class HgInit extends DumbAwareAction {
       return;
     }
 
-    // provide window to select the root directory (TODO: an option to select the whole project)
-    final FileChooserDescriptor fcd = new FileChooserDescriptor(false, true, false, false, false, false) {
-      public void validateSelectedFiles(VirtualFile[] files) throws Exception {
-        if (HgUtil.isHgRoot(files[0])) {
-          throw new ConfigurationException(HgVcsMessages.message("hg4idea.init.this.is.hg.root", files[0].getPresentableUrl()));
-        }
-      }
-    };
-    fcd.setTitle(HgVcsMessages.message("hg4idea.init.destination.directory.title"));
-    fcd.setDescription(HgVcsMessages.message("hg4idea.init.destination.directory.description"));
-    fcd.setHideIgnored(false);
-    final VirtualFile projectDir = project.getBaseDir();
-    final VirtualFile[] files = FileChooser.chooseFiles(project, fcd, projectDir);
-    if (files.length == 0) {
+    // provide window to select the root directory
+    final HgInitDialog hgInitDialog = new HgInitDialog(project);
+    hgInitDialog.show();
+    if (!hgInitDialog.isOK()) {
+      return;
+    }
+    final VirtualFile selectedRoot = hgInitDialog.getSelectedFolder();
+    if (selectedRoot == null) {
       return;
     }
-    final VirtualFile selectedRoot = files[0];
 
-    // check if it is not yet under mercurial
+    // check if it the project is not yet under mercurial and provide some options in that case
     final VirtualFile vcsRoot = HgUtil.getNearestHgRoot(selectedRoot);
     VirtualFile mapRoot = selectedRoot;
     if (vcsRoot != null) {
-      final HgInitParentDialog dialog = new HgInitParentDialog(project,
+      final HgInitAlreadyUnderHgDialog dialog = new HgInitAlreadyUnderHgDialog(project,
                                                    selectedRoot.getPresentableUrl(), vcsRoot.getPresentableUrl());
       dialog.show();
       if (!dialog.isOK()) {
         return;
       }
 
-      if (dialog.getAnswer() == HgInitParentDialog.Answer.CREATE_PROJECT_AT_PARENT) {
+      if (dialog.getAnswer() == HgInitAlreadyUnderHgDialog.Answer.CREATE_PROJECT_AT_PARENT) {
         NewProjectUtil.createNewProject(project, vcsRoot.getPath());
         return;
-      } else if (dialog.getAnswer() == HgInitParentDialog.Answer.USE_PARENT_REPO_BUT_THIS_PROJECT) {
+      } else if (dialog.getAnswer() == HgInitAlreadyUnderHgDialog.Answer.USE_PARENT_REPO_BUT_THIS_PROJECT) {
         mapRoot = vcsRoot;
-      } else {
+      } else if (dialog.getAnswer() == HgInitAlreadyUnderHgDialog.Answer.CREATE_REPO_HERE) {
         (new HgInitCommand(project)).execute(selectedRoot);
       }
+    } else { // no parent repository => creating the repository here.
+       (new HgInitCommand(project)).execute(selectedRoot);  
     }
 
     // update vcs directory mappings
     mapRoot.refresh(false, false);
-    final String path = mapRoot.equals(projectDir) ? "" : mapRoot.getPath();
+    final String path = mapRoot.equals(project.getBaseDir()) ? "" : mapRoot.getPath();
     final ProjectLevelVcsManager vcsManager = ProjectLevelVcsManager.getInstance(project);
     final List<VcsDirectoryMapping> vcsDirectoryMappings = new ArrayList<VcsDirectoryMapping>(vcsManager.getDirectoryMappings());
     VcsDirectoryMapping mapping = new VcsDirectoryMapping(path, HgVcs.VCS_NAME);
similarity index 57%
rename from plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgInitParentDialog.form
rename to plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgInitDialog.form
index a8939df6cbab57b791f769fc4dba973580fc9061..712cb49e42fed69cfe90d18c29676dbbc98938d3 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.zmlx.hg4idea.ui.HgInitParentDialog">
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.zmlx.hg4idea.ui.HgInitDialog">
   <grid id="cbd77" binding="contentPane" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
     <margin top="10" left="10" bottom="10" right="10"/>
     <constraints>
@@ -8,7 +8,7 @@
     <properties/>
     <border type="none"/>
     <children>
-      <grid id="e3588" layout-manager="GridLayoutManager" row-count="4" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+      <grid id="e3588" layout-manager="GridLayoutManager" row-count="4" 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="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"/>
         <properties/>
         <border type="none"/>
         <children>
-          <component id="1b523" class="javax.swing.JRadioButton" binding="myCreateNewRepositoryHereRadioButton" default-binding="true">
+          <component id="c5d0e" class="javax.swing.JRadioButton" binding="myCreateRepositoryForTheRadioButton" default-binding="true">
             <constraints>
-              <grid row="3" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+              <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
             </constraints>
             <properties>
-              <text resource-bundle="org/zmlx/hg4idea/HgVcsMessages" key="hg4idea.init.already.under.hg.option.create.repo.here"/>
+              <selected value="true"/>
+              <text resource-bundle="org/zmlx/hg4idea/HgVcsMessages" key="hg4idea.init.dialog.option.create.repository.for.whole.project"/>
             </properties>
           </component>
-          <vspacer id="4f601">
+          <component id="6bbb3" class="javax.swing.JRadioButton" binding="mySelectWhereToCreateRadioButton" default-binding="true">
             <constraints>
-              <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
-            </constraints>
-          </vspacer>
-          <component id="ef06d" class="javax.swing.JRadioButton" binding="myUseParentRepoButThisProjectButton">
-            <constraints>
-              <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+              <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
             </constraints>
             <properties>
-              <text resource-bundle="org/zmlx/hg4idea/HgVcsMessages" key="hg4idea.init.already.under.hg.option.use.parent"/>
+              <text resource-bundle="org/zmlx/hg4idea/HgVcsMessages" key="hg4idea.init.dialog.option.select.folder"/>
             </properties>
           </component>
-          <component id="f180f" class="javax.swing.JRadioButton" binding="myUseParentRepoAndCreateProjectButton">
+          <component id="d4405" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="myTextFieldBrowser">
             <constraints>
-              <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+              <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
             </constraints>
             <properties>
-              <text resource-bundle="org/zmlx/hg4idea/HgVcsMessages" key="hg4idea.init.already.under.hg.option.create.project.at.parent"/>
+              <enabled value="false"/>
             </properties>
           </component>
-          <component id="244a3" class="com.intellij.openapi.ui.TitlePanel" binding="myTitlePanel" custom-create="true">
+          <vspacer id="75b54">
             <constraints>
-              <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
+              <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
             </constraints>
-            <properties/>
-          </component>
+          </vspacer>
         </children>
       </grid>
     </children>
   </grid>
+  <buttonGroups>
+    <group name="buttonGroup">
+      <member id="6bbb3"/>
+      <member id="c5d0e"/>
+    </group>
+  </buttonGroups>
 </form>
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgInitDialog.java b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgInitDialog.java
new file mode 100644 (file)
index 0000000..1c7d515
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2000-2010 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.zmlx.hg4idea.ui;
+
+import com.intellij.openapi.fileChooser.FileChooser;
+import com.intellij.openapi.fileChooser.FileChooserDescriptor;
+import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.ui.TextFieldWithBrowseButton;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.vcsUtil.VcsUtil;
+import org.jetbrains.annotations.Nullable;
+import org.zmlx.hg4idea.HgUtil;
+import org.zmlx.hg4idea.HgVcsMessages;
+
+import javax.swing.*;
+import javax.swing.event.CaretEvent;
+import javax.swing.event.CaretListener;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+/**
+ * The HgInitDialog appears when user wants to create new Mercurial repository, in response to the
+ * {@link org.zmlx.hg4idea.action.HgInit} action.
+ * It provides two options - create repository for the whole project or select a directory for the repository.
+ * Also if the project directory already is a mercurial root, then no options are provided.
+ * Instead a file chooser appears to select directory for the repository.  
+ *
+ * @see org.zmlx.hg4idea.action.HgInit
+ * @author Kirill Likhodedov
+ */
+public class HgInitDialog extends DialogWrapper {
+  private JPanel contentPane;
+  private JRadioButton myCreateRepositoryForTheRadioButton;
+  private JRadioButton mySelectWhereToCreateRadioButton;
+  private TextFieldWithBrowseButton myTextFieldBrowser;
+  private final Project myProject;
+  private VirtualFile mySelectedDir;
+  private FileChooserDescriptor myFileDescriptor;
+  private boolean myIsProjectBaseDirHgRoot; // basing on this field, show options or invoke file chooser at once
+
+  public HgInitDialog(Project project) {
+    super(project);
+    myProject = project;
+    myIsProjectBaseDirHgRoot = HgUtil.isHgRoot(myProject.getBaseDir());
+    init();
+  }
+
+  @Override
+  protected void init() {
+    super.init();
+    setTitle(HgVcsMessages.message("hg4idea.init.dialog.title"));
+    mySelectedDir = myProject.getBaseDir();
+
+    mySelectWhereToCreateRadioButton.addActionListener(new ActionListener() {
+      public void actionPerformed(ActionEvent e) {
+        myTextFieldBrowser.setEnabled(true);
+        updateEverything();
+      }
+    });
+    myCreateRepositoryForTheRadioButton.addActionListener(new ActionListener() {
+      public void actionPerformed(ActionEvent e) {
+        myTextFieldBrowser.setEnabled(false);
+        updateEverything();
+      }
+    });
+    myTextFieldBrowser.getTextField().addCaretListener(new CaretListener() {
+      public void caretUpdate(CaretEvent e) {
+        updateEverything();
+      }
+    });
+
+    myFileDescriptor = new FileChooserDescriptor(false, true, false, false, false, false) {
+      public void validateSelectedFiles(VirtualFile[] files) throws Exception {
+        if (HgUtil.isHgRoot(files[0])) {
+          throw new ConfigurationException(HgVcsMessages.message("hg4idea.init.this.is.hg.root", files[0].getPresentableUrl()));
+        }
+        updateEverything();
+      }
+    };
+    myFileDescriptor.setHideIgnored(false);
+    myTextFieldBrowser.addBrowseFolderListener(HgVcsMessages.message("hg4idea.init.destination.directory.title"),
+                                               HgVcsMessages.message("hg4idea.init.destination.directory.description"),
+                                               myProject, myFileDescriptor);
+  }
+
+  /**
+   * Show the dialog OR show a FileChooser to select target directory.
+   */
+  @Override
+  public void show() {
+    if (myIsProjectBaseDirHgRoot) {
+      final VirtualFile[] files = FileChooser.chooseFiles(myProject, myFileDescriptor, myProject.getBaseDir());
+      mySelectedDir = (files.length == 0 ? null : files[0]);
+    } else {
+      super.show();
+    }
+  }
+
+  @Override
+  public boolean isOK() {
+    if (myIsProjectBaseDirHgRoot) {
+      return mySelectedDir != null;
+    }
+    return super.isOK();
+  }
+
+  @Nullable
+  public VirtualFile getSelectedFolder() {
+    return mySelectedDir;
+  }
+
+  @Override
+  protected JComponent createCenterPanel() {
+    return contentPane;
+  }
+
+  /**
+   * Based on the selected option and entered path to the target directory,
+   * enable/disable the 'OK' button, show error text and update mySelectedDir. 
+   */
+  private void updateEverything() {
+    if (myCreateRepositoryForTheRadioButton.isSelected()) {
+      enableOKAction();
+      mySelectedDir = myProject.getBaseDir();
+    } else {
+      final VirtualFile vf = VcsUtil.getVirtualFile(myTextFieldBrowser.getText());
+      if (vf == null) {
+        disableOKAction();
+        mySelectedDir = null;
+        return;
+      }
+      vf.refresh(false, false);
+      if (vf.exists() && vf.isValid() && vf.isDirectory()) {
+        enableOKAction();
+        mySelectedDir = vf;
+      } else {
+        disableOKAction();
+        mySelectedDir = null;
+      }
+    }
+  }
+
+  private void enableOKAction() {
+    setErrorText(null);
+    setOKActionEnabled(true);
+  }
+
+  private void disableOKAction() {
+    setErrorText(HgVcsMessages.message("hg4idea.init.dialog.incorrect.path"));
+    setOKActionEnabled(false);
+  }
+
+}