[Mercurial] Better HgInit: provide options if creating in directory which is already...
authorKirill Likhodedov <kirill.likhodedov@jetbrains.com>
Fri, 18 Jun 2010 07:57:25 +0000 (11:57 +0400)
committerKirill Likhodedov <kirill.likhodedov@jetbrains.com>
Fri, 18 Jun 2010 07:57:25 +0000 (11:57 +0400)
plugins/hg4idea/hg4idea.iml
plugins/hg4idea/resources/org/zmlx/hg4idea/HgVcsMessages.properties
plugins/hg4idea/src/org/zmlx/hg4idea/action/HgInit.java
plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgInitParentDialog.form [new file with mode: 0644]
plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgInitParentDialog.java [new file with mode: 0644]
plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgPullDialog.java

index b8677676d4935004731189470d101a66e64ae720..994b8de424836a3884879faec0bc5400e29e56b4 100644 (file)
@@ -13,6 +13,8 @@
     <orderEntry type="library" name="commons-lang" level="project" />
     <orderEntry type="library" scope="TEST" name="TestNG" level="project" />
     <orderEntry type="module" module-name="testFramework" scope="TEST" />
+    <orderEntry type="module" module-name="idea-ui" />
+    <orderEntry type="module" module-name="platform-api" />
   </component>
 </module>
 
index b0a29c223b4eb7715496ef7fb63036db55f622b5..96db4c09061dcf5be5ac26a869dfa5e7d600e399 100644 (file)
@@ -23,8 +23,13 @@ hg4idea.commit=Commit
 
 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.error.already.under.hg=The selected directory {0} is already under hg.
-hg4idea.init.error.title=hg init Error
+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.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.
+hg4idea.init.already.under.hg.option.use.parent=Use parent repository, but keep working in this project.
+hg4idea.init.already.under.hg.option.create.repo.here=Create new repository here.
 
 hg4idea.clone.title=Clone Mercurial Repostiroy
 hg4idea.clone.button.clone=Clone
index 5dae5be0ea2521be64d0acc05e3ac5fd4d9f0332..d5af79f433015cf28380db5d6d002104c7e5a7e3 100644 (file)
@@ -1,21 +1,23 @@
 package org.zmlx.hg4idea.action;
 
+import com.intellij.ide.impl.NewProjectUtil;
 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.fileChooser.FileChooserDescriptorFactory;
+import com.intellij.openapi.options.ConfigurationException;
 import com.intellij.openapi.project.DumbAwareAction;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.Messages;
 import com.intellij.openapi.vcs.ProjectLevelVcsManager;
 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 java.util.ArrayList;
 import java.util.List;
@@ -39,37 +41,50 @@ public class HgInit extends DumbAwareAction {
       return;
     }
 
-    // 1. provide window to select the root directory (possibly with an option to select project directory
-    // TODO: dialog: probably the user wants to put the whole project under git, so the root dir of the project is git repo root. No need to select the folder in that case.
-    final FileChooserDescriptor fcd = FileChooserDescriptorFactory.createSingleFolderDescriptor();
+    // 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 baseDir = project.getBaseDir();
-    final VirtualFile[] files = FileChooser.chooseFiles(project, fcd, baseDir);
+    final VirtualFile projectDir = project.getBaseDir();
+    final VirtualFile[] files = FileChooser.chooseFiles(project, fcd, projectDir);
     if (files.length == 0) {
       return;
     }
-    final VirtualFile root = files[0];
-
-    // 2. check if it is not yet under mercurial
-    final HgVcs hgVcs = HgVcs.getInstance(project);
-    if (hgVcs.isVersionedDirectory(root)) {
-      Messages.showErrorDialog(project, HgVcsMessages.message("hg4idea.init.error.already.under.hg", root.getPresentableUrl()),
-                               HgVcsMessages.message("hg4idea.init.error.title"));
-      return;
-    }
+    final VirtualFile selectedRoot = files[0];
 
+    // check if it is not yet under mercurial
+    final VirtualFile vcsRoot = HgUtil.getNearestHgRoot(selectedRoot);
+    VirtualFile mapRoot = selectedRoot;
+    if (vcsRoot != null) {
+      final HgInitParentDialog dialog = new HgInitParentDialog(project,
+                                                   selectedRoot.getPresentableUrl(), vcsRoot.getPresentableUrl());
+      dialog.show();
+      if (!dialog.isOK()) {
+        return;
+      }
 
-    // 3. Execute hg init
-    (new HgInitCommand(project)).execute(root);
-    //TODO: handle errors here
+      if (dialog.getAnswer() == HgInitParentDialog.Answer.CREATE_PROJECT_AT_PARENT) {
+        NewProjectUtil.createNewProject(project, vcsRoot.getPath());
+        return;
+      } else if (dialog.getAnswer() == HgInitParentDialog.Answer.USE_PARENT_REPO_BUT_THIS_PROJECT) {
+        mapRoot = vcsRoot;
+      } else {
+        (new HgInitCommand(project)).execute(selectedRoot);
+      }
+    }
 
-    // 4. update vcs directory mappings
-    root.refresh(false, false);
-    final String path = root.equals(baseDir) ? "" : root.getPath();
-    ProjectLevelVcsManager vcs = ProjectLevelVcsManager.getInstance(project);
-    final List<VcsDirectoryMapping> vcsDirectoryMappings = new ArrayList<VcsDirectoryMapping>(vcs.getDirectoryMappings());
+    // update vcs directory mappings
+    mapRoot.refresh(false, false);
+    final String path = mapRoot.equals(projectDir) ? "" : 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);
     for (int i = 0; i < vcsDirectoryMappings.size(); i++) {
       final VcsDirectoryMapping m = vcsDirectoryMappings.get(i);
@@ -88,8 +103,8 @@ public class HgInit extends DumbAwareAction {
     if (mapping != null) {
       vcsDirectoryMappings.add(mapping);
     }
-    vcs.setDirectoryMappings(vcsDirectoryMappings);
-    vcs.updateActiveVcss();
+    vcsManager.setDirectoryMappings(vcsDirectoryMappings);
+    vcsManager.updateActiveVcss();
   }
 
   @Override
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgInitParentDialog.form b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgInitParentDialog.form
new file mode 100644 (file)
index 0000000..a8939df
--- /dev/null
@@ -0,0 +1,58 @@
+<?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">
+  <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>
+      <xy x="48" y="54" width="436" height="297"/>
+    </constraints>
+    <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">
+        <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"/>
+        </constraints>
+        <properties/>
+        <border type="none"/>
+        <children>
+          <component id="1b523" class="javax.swing.JRadioButton" binding="myCreateNewRepositoryHereRadioButton" 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"/>
+            </constraints>
+            <properties>
+              <text resource-bundle="org/zmlx/hg4idea/HgVcsMessages" key="hg4idea.init.already.under.hg.option.create.repo.here"/>
+            </properties>
+          </component>
+          <vspacer id="4f601">
+            <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"/>
+            </constraints>
+            <properties>
+              <text resource-bundle="org/zmlx/hg4idea/HgVcsMessages" key="hg4idea.init.already.under.hg.option.use.parent"/>
+            </properties>
+          </component>
+          <component id="f180f" class="javax.swing.JRadioButton" binding="myUseParentRepoAndCreateProjectButton">
+            <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"/>
+            </constraints>
+            <properties>
+              <text resource-bundle="org/zmlx/hg4idea/HgVcsMessages" key="hg4idea.init.already.under.hg.option.create.project.at.parent"/>
+            </properties>
+          </component>
+          <component id="244a3" class="com.intellij.openapi.ui.TitlePanel" binding="myTitlePanel" custom-create="true">
+            <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"/>
+            </constraints>
+            <properties/>
+          </component>
+        </children>
+      </grid>
+    </children>
+  </grid>
+</form>
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgInitParentDialog.java b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgInitParentDialog.java
new file mode 100644 (file)
index 0000000..80efa91
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * 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.project.Project;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.ui.TitlePanel;
+import org.zmlx.hg4idea.HgVcsMessages;
+
+import javax.swing.*;
+
+/**
+ * The dialog which appears, when user wants to create a Mercurial repository in the folder,
+ * which is already under Mercurial.
+ * Provides several options to choose.
+ */
+public class HgInitParentDialog extends DialogWrapper {
+  private JPanel contentPane;
+  private JRadioButton myCreateNewRepositoryHereRadioButton;
+  private JRadioButton myUseParentRepoButThisProjectButton;
+  private JRadioButton myUseParentRepoAndCreateProjectButton;
+  private TitlePanel myTitlePanel;
+  private String myParentRoot;
+  private String mySelectedRoot;
+
+  public enum Answer {
+    CREATE_PROJECT_AT_PARENT,
+    USE_PARENT_REPO_BUT_THIS_PROJECT,
+    CREATE_REPO_HERE
+  }
+
+  public HgInitParentDialog(Project project, String selectedRoot, String parentRoot) {
+    super(project, false);
+    mySelectedRoot = selectedRoot;
+    myParentRoot = parentRoot;
+    setTitle(HgVcsMessages.message("hg4idea.init.already.under.hg.dialog.title"));
+    init();
+  }
+
+  public Answer getAnswer() {
+    if (myCreateNewRepositoryHereRadioButton.isSelected()) {
+      return Answer.CREATE_REPO_HERE;
+    } else if (myUseParentRepoAndCreateProjectButton.isSelected()) {
+      return Answer.CREATE_PROJECT_AT_PARENT;
+    } else {
+      return Answer.USE_PARENT_REPO_BUT_THIS_PROJECT;
+    }
+  }
+
+  @Override
+  protected void init() {
+    super.init();
+    final ButtonGroup buttonGroup = new ButtonGroup();
+    buttonGroup.add(myCreateNewRepositoryHereRadioButton);
+    buttonGroup.add(myUseParentRepoAndCreateProjectButton);
+    buttonGroup.add(myUseParentRepoButThisProjectButton);
+  }
+
+  @Override
+  protected JComponent createCenterPanel() {
+    return contentPane;
+  }
+
+  private void createUIComponents() {
+    myTitlePanel = new TitlePanel(HgVcsMessages.message("hg4idea.init.already.under.hg.title"),
+                                  HgVcsMessages.message("hg4idea.init.already.under.hg.description", mySelectedRoot, myParentRoot));
+  }
+  
+}
\ No newline at end of file
index dd76ce5f0aa82da7df5d1df66a248296afd431e0..c3c198d8272950e2a90e45eabf0286600fba91f2 100644 (file)
@@ -95,43 +95,4 @@ public class HgPullDialog extends DialogWrapper {
     setOKActionEnabled(StringUtils.isNotBlank(sourceTxt.getText()));
   }
 
-  {
-// GUI initializer generated by IntelliJ IDEA GUI Designer
-// >>> IMPORTANT!! <<<
-// DO NOT EDIT OR ADD ANY CODE HERE!
-    $$$setupUI$$$();
-  }
-
-  /**
-   * Method generated by IntelliJ IDEA GUI Designer
-   * >>> IMPORTANT!! <<<
-   * DO NOT edit this method OR call it in your code!
-   *
-   * @noinspection ALL
-   */
-  private void $$$setupUI$$$() {
-    mainPanel = new JPanel();
-    mainPanel.setLayout(new GridLayoutManager(3, 1, new Insets(0, 0, 0, 0), -1, -1));
-    hgRepositorySelector = new HgRepositorySelectorComponent();
-    mainPanel.add(hgRepositorySelector.$$$getRootComponent$$$(), new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false));
-    final Spacer spacer1 = new Spacer();
-    mainPanel.add(spacer1, new GridConstraints(2, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_VERTICAL, 1, GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false));
-    final JPanel panel1 = new JPanel();
-    panel1.setLayout(new GridLayoutManager(2, 2, new Insets(0, 0, 0, 0), -1, -1));
-    mainPanel.add(panel1, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false));
-    final JLabel label1 = new JLabel();
-    label1.setText("Pull From:");
-    panel1.add(label1, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
-    final Spacer spacer2 = new Spacer();
-    panel1.add(spacer2, new GridConstraints(0, 1, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, 1, null, null, null, 0, false));
-    sourceTxt = new JTextField();
-    panel1.add(sourceTxt, new GridConstraints(1, 0, 1, 2, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
-  }
-
-  /**
-   * @noinspection ALL
-   */
-  public JComponent $$$getRootComponent$$$() {
-    return mainPanel;
-  }
 }