Redesign dialogs

This commit is contained in:
Nikolay Krasko
2013-03-05 15:05:15 +04:00
parent d5195382fa
commit a6d5ad4155
7 changed files with 127 additions and 74 deletions
@@ -28,7 +28,6 @@ import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.plugin.JetPluginUtil;
import org.jetbrains.jet.plugin.framework.ui.CreateJavaScriptLibraryDialog;
import org.jetbrains.jet.plugin.framework.ui.FileUIUtils;
import org.jetbrains.jet.utils.KotlinPaths;
@@ -36,10 +35,7 @@ import org.jetbrains.jet.utils.PathUtil;
import javax.swing.*;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
public class JSLibraryDescription extends CustomLibraryDescription {
public static final LibraryKind KOTLIN_JAVASCRIPT_KIND = LibraryKind.create("kotlin-js-stdlib");
@@ -69,15 +65,24 @@ public class JSLibraryDescription extends CustomLibraryDescription {
return null;
}
String copyIntoPath = dialog.getCopyIntoPath();
if (copyIntoPath != null) {
List<File> copyFiles = new ArrayList<File>();
Map<File, String> copyToPaths = new HashMap<File, String>();
if (dialog.isCopyLibraryFiles()) {
String copyIntoPath = dialog.getCopyLibraryIntoPath();
assert copyIntoPath != null;
if (dialog.isCopyLibraryFiles()) copyFiles.add(libraryFile);
if (dialog.isCopyECMA3()) copyFiles.add(paths.getJsLibJsPath());
copyToPaths.put(libraryFile, copyIntoPath);
}
if (dialog.isCopyJS()) {
String copyIntoPath = dialog.getCopyJsIntoPath();
assert copyIntoPath != null;
copyToPaths.put(paths.getJsLibJsPath(), copyIntoPath);
}
if (!copyToPaths.isEmpty()) {
Map<File,File> copiedFiles =
FileUIUtils.copyWithOverwriteDialog(parentComponent, JAVA_SCRIPT_LIBRARY_CREATION, copyIntoPath, copyFiles);
FileUIUtils.copyWithOverwriteDialog(parentComponent, JAVA_SCRIPT_LIBRARY_CREATION, copyToPaths);
if (copiedFiles == null) {
return null;
}
@@ -19,7 +19,6 @@ package org.jetbrains.jet.plugin.framework.ui;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.DocumentAdapter;
import com.intellij.util.EventDispatcher;
import org.jetbrains.annotations.NotNull;
@@ -38,7 +37,11 @@ public class CopyIntoPanel {
private boolean hasErrorsState;
public CopyIntoPanel(@Nullable Project project, @NotNull VirtualFile contextDirectory) {
public CopyIntoPanel(@Nullable Project project, @NotNull String defaultPath) {
this(project, defaultPath, null);
}
public CopyIntoPanel(@Nullable Project project, @NotNull String defaultPath, @Nullable String labelText) {
copyIntoField.addBrowseFolderListener(
"Copy Into...", "Choose folder where files will be copied", project,
FileChooserDescriptorFactory.createSingleFolderDescriptor());
@@ -49,8 +52,20 @@ public class CopyIntoPanel {
}
});
if (labelText != null) {
String text = labelText.replace("&", "");
int mnemonicIndex = labelText.indexOf("&");
char mnemonicChar = mnemonicIndex != -1 && (mnemonicIndex + 1) < labelText.length() ? labelText.charAt(mnemonicIndex + 1) : 0;
copyIntoLabel.setText(text);
copyIntoLabel.setDisplayedMnemonic(mnemonicChar);
copyIntoLabel.setDisplayedMnemonicIndex(mnemonicIndex);
}
copyIntoLabel.setLabelFor(copyIntoField.getTextField());
copyIntoField.getTextField().setText(FileUIUtils.getDefaultLibraryFolder(project, contextDirectory));
copyIntoField.getTextField().setText(defaultPath);
copyIntoField.getTextField().setColumns(40);
updateComponents();
}
@@ -14,7 +14,7 @@
</constraints>
</vspacer>
<grid id="46726" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="15" left="0" bottom="0" right="0"/>
<margin top="10" left="0" bottom="0" right="0"/>
<constraints>
<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>
@@ -26,7 +26,8 @@
<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 value="Make local copy of library (could be stored in VCS) "/>
<selected value="true"/>
<text value="&amp;Make local copy of library (could be stored in VCS) "/>
</properties>
</component>
<grid id="e47d8" binding="copyIntoPanelPlace" layout-manager="BorderLayout" hgap="0" vgap="0">
@@ -45,7 +45,7 @@ public class CreateJavaLibraryDialog extends DialogWrapper {
ChooseCompilerSourcePanel compilerSourcePanel = new ChooseCompilerSourcePanel();
compilerSourcePanelPlace.add(compilerSourcePanel.getContentPane(), BorderLayout.CENTER, 0);
copyIntoPanel = new CopyIntoPanel(project, contextDirectory);
copyIntoPanel = new CopyIntoPanel(project, FileUIUtils.createRelativePath(project, contextDirectory, "lib"));
copyIntoPanel.addValidityListener(new ValidityListener() {
@Override
public void validityChanged(boolean isValid) {
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.jet.plugin.framework.ui.CreateJavaScriptLibraryDialog">
<grid id="cbd77" binding="contentPane" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="cbd77" binding="contentPane" layout-manager="GridLayoutManager" row-count="3" 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="48" y="54" width="436" height="297"/>
@@ -10,13 +10,13 @@
<children>
<vspacer id="bb37c">
<constraints>
<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"/>
<grid row="2" 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>
</vspacer>
<grid id="46726" layout-manager="GridLayoutManager" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<grid id="46726" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="10" left="0" bottom="0" right="0"/>
<constraints>
<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"/>
<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"/>
@@ -26,21 +26,30 @@
<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 value="&amp;Library files"/>
<selected value="true"/>
<text value="&amp;Make local copy of library (could be stored in VCS) "/>
</properties>
</component>
<component id="dd25b" class="javax.swing.JCheckBox" binding="ECMAScript3JavaScriptRuntimeCheckBox" default-binding="true">
<component id="dd25b" class="javax.swing.JCheckBox" binding="copyJSRuntimeCheckbox" default-binding="true">
<constraints>
<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"/>
<grid row="2" 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>
<selected value="true"/>
<text value="EC&amp;MAScript 3 JavaScript runtime file"/>
<text value="&amp;Get JavaScript runtime files"/>
</properties>
</component>
<grid id="11e35" binding="copyIntoPanelPlace" layout-manager="BorderLayout" hgap="0" vgap="0">
<grid id="11e35" binding="copyJSIntoPanelPlace" layout-manager="BorderLayout" hgap="0" vgap="0">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="3" 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="3" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children/>
</grid>
<grid id="2bd15" binding="copyHeadersIntoPanelPlace" layout-manager="BorderLayout" hgap="0" vgap="0">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="3" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
@@ -48,14 +57,6 @@
</grid>
</children>
</grid>
<component id="7c0b3" class="com.intellij.ui.TitledSeparator">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Copy Into Project"/>
</properties>
</component>
<grid id="d209b" binding="compilerSourcePanelPlace" layout-manager="BorderLayout" hgap="0" vgap="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"/>
@@ -12,13 +12,15 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class CreateJavaScriptLibraryDialog extends DialogWrapper {
private final CopyIntoPanel copyIntoPanel;
private final CopyIntoPanel copyJSIntoPanel;
private final CopyIntoPanel copyLibraryIntoPanel;
private JPanel contentPane;
private JCheckBox copyLibraryCheckbox;
private JCheckBox ECMAScript3JavaScriptRuntimeCheckBox;
private JCheckBox copyJSRuntimeCheckbox;
private JPanel compilerSourcePanelPlace;
private JPanel copyIntoPanelPlace;
private JPanel copyJSIntoPanelPlace;
private JPanel copyHeadersIntoPanelPlace;
public CreateJavaScriptLibraryDialog(@Nullable Project project, @NotNull String title, VirtualFile contextDirectory) {
super(project);
@@ -30,14 +32,23 @@ public class CreateJavaScriptLibraryDialog extends DialogWrapper {
ChooseCompilerSourcePanel compilerSourcePanel = new ChooseCompilerSourcePanel();
compilerSourcePanelPlace.add(compilerSourcePanel.getContentPane(), BorderLayout.CENTER);
copyIntoPanel = new CopyIntoPanel(project, contextDirectory);
copyIntoPanel.addValidityListener(new ValidityListener() {
copyJSIntoPanel = new CopyIntoPanel(project, FileUIUtils.createRelativePath(project, contextDirectory, "script"), "&Script directory:");
copyJSIntoPanel.addValidityListener(new ValidityListener() {
@Override
public void validityChanged(boolean isValid) {
updateComponents();
}
});
copyIntoPanelPlace.add(copyIntoPanel.getContentPane(), BorderLayout.CENTER);
copyJSIntoPanelPlace.add(copyJSIntoPanel.getContentPane(), BorderLayout.CENTER);
copyLibraryIntoPanel = new CopyIntoPanel(project, FileUIUtils.createRelativePath(project, contextDirectory, "lib"), "&Lib directory:");
copyLibraryIntoPanel.addValidityListener(new ValidityListener() {
@Override
public void validityChanged(boolean isValid) {
updateComponents();
}
});
copyHeadersIntoPanelPlace.add(copyLibraryIntoPanel.getContentPane(), BorderLayout.CENTER);
ActionListener updateComponentsListener = new ActionListener() {
@Override
@@ -47,29 +58,34 @@ public class CreateJavaScriptLibraryDialog extends DialogWrapper {
};
copyLibraryCheckbox.addActionListener(updateComponentsListener);
ECMAScript3JavaScriptRuntimeCheckBox.addActionListener(updateComponentsListener);
copyJSRuntimeCheckbox.addActionListener(updateComponentsListener);
updateComponents();
}
@Nullable
public String getCopyIntoPath() {
return copyIntoPanel.getPath();
public String getCopyJsIntoPath() {
return copyJSIntoPanel.getPath();
}
@Nullable
public String getCopyLibraryIntoPath() {
return copyLibraryIntoPanel.getPath();
}
public boolean isCopyLibraryFiles() {
return copyLibraryCheckbox.isSelected();
}
public boolean isCopyECMA3() {
return ECMAScript3JavaScriptRuntimeCheckBox.isSelected();
public boolean isCopyJS() {
return copyJSRuntimeCheckbox.isSelected();
}
private void updateComponents() {
copyIntoPanel.setEnabled(copyLibraryCheckbox.isSelected() ||
ECMAScript3JavaScriptRuntimeCheckBox.isSelected());
copyLibraryIntoPanel.setEnabled(copyLibraryCheckbox.isSelected());
copyJSIntoPanel.setEnabled(copyJSRuntimeCheckbox.isSelected());
setOKActionEnabled(!copyIntoPanel.hasErrors());
setOKActionEnabled(!(copyJSIntoPanel.hasErrors() || copyLibraryIntoPanel.hasErrors()));
}
@Nullable
@@ -16,9 +16,10 @@
package org.jetbrains.jet.plugin.framework.ui;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.intellij.ide.util.projectWizard.ProjectWizardUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
@@ -35,7 +36,6 @@ import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.List;
public class FileUIUtils {
private FileUIUtils() {
@@ -47,7 +47,7 @@ public class FileUIUtils {
@NotNull String messagesTitle,
@NotNull String destinationFolder,
@NotNull File file) {
Map<File, File> copiedFiles = copyWithOverwriteDialog(parent, messagesTitle, destinationFolder, ImmutableList.of(file));
Map<File, File> copiedFiles = copyWithOverwriteDialog(parent, messagesTitle, ImmutableMap.of(file, destinationFolder));
if (copiedFiles == null) {
return null;
}
@@ -62,40 +62,49 @@ public class FileUIUtils {
public static Map<File, File> copyWithOverwriteDialog(
@NotNull Component parent,
@NotNull String messagesTitle,
@NotNull String destinationFolder,
@NotNull List<File> files
@NotNull Map<File, String> filesWithDestinations
) {
if (!ProjectWizardUtil.createDirectoryIfNotExists("Destination folder", destinationFolder, false)) {
Messages.showErrorDialog(String.format("Error during folder creating '%s'", destinationFolder), messagesTitle + ". Error");
return null;
}
File folder = new File(destinationFolder);
Set<String> fileNames = new HashSet<String>();
Map<File, File> targetFiles = new LinkedHashMap<File, File>(files.size());
for (File file : files) {
Map<File, File> targetFiles = new LinkedHashMap<File, File>(filesWithDestinations.size());
for (Map.Entry<File, String> sourceToDestination : filesWithDestinations.entrySet()) {
File file = sourceToDestination.getKey();
String destinationPath = sourceToDestination.getValue();
String fileName = file.getName();
if (!fileNames.add(fileName)) {
throw new IllegalArgumentException("There are several files with the same name: " + fileName);
}
targetFiles.put(file, new File(folder, fileName));
targetFiles.put(file, new File(destinationPath, fileName));
}
Collection<File> existentFiles = Collections2.filter(targetFiles.values(), new Predicate<File>() {
Collection<Map.Entry<File, File>> existentFiles = Collections2.filter(targetFiles.entrySet(), new Predicate<Map.Entry<File, File>>() {
@Override
public boolean apply(@Nullable File file) {
assert file != null;
return file.exists();
public boolean apply(@Nullable Map.Entry<File, File> sourceToTarget) {
assert sourceToTarget != null;
return sourceToTarget.getValue().exists();
}
});
if (!existentFiles.isEmpty()) {
String message = existentFiles.size() == 1 ?
String.format("File \"%s\" is already exist in %s.\nDo you want to overwrite it?", existentFiles.iterator().next().getName(), folder.getAbsolutePath()) :
String.format("Several files are already exist in %s:\n%s\nDo you want to overwrite them?", folder.getAbsolutePath(), StringUtil.join(existentFiles, "\n"));
String message;
if (existentFiles.size() == 1) {
File conflictingFile = existentFiles.iterator().next().getValue();
message = String.format("File \"%s\" already exists in %s.\nDo you want to overwrite it?", conflictingFile.getName(),
conflictingFile.getParentFile().getAbsolutePath());
}
else {
Collection<File> conflictFiles = Collections2.transform(existentFiles, new Function<Map.Entry<File, File>, File>() {
@Override
public File apply(@Nullable Map.Entry<File, File> pair) {
assert pair != null;
return pair.getValue();
}
});
message = String.format("Files already exist:\n%s\nDo you want to overwrite them?", StringUtil.join(conflictFiles, "\n"));
}
int replaceIfExist = Messages.showYesNoDialog(
null,
@@ -112,6 +121,12 @@ public class FileUIUtils {
for (Map.Entry<File, File> sourceToTarget : targetFiles.entrySet()) {
try {
String destinationPath = sourceToTarget.getValue().getParentFile().getAbsolutePath();
if (!ProjectWizardUtil.createDirectoryIfNotExists("Destination folder", destinationPath, false)) {
Messages.showErrorDialog(String.format("Error during folder creating '%s'", destinationPath), messagesTitle + ". Error");
return null;
}
FileUtil.copy(sourceToTarget.getKey(), sourceToTarget.getValue());
LocalFileSystem.getInstance().refreshAndFindFileByIoFile(sourceToTarget.getValue());
}
@@ -125,7 +140,7 @@ public class FileUIUtils {
}
@NotNull
public static String getDefaultLibraryFolder(@Nullable Project project, @Nullable VirtualFile contextDirectory) {
public static String createRelativePath(@Nullable Project project, @Nullable VirtualFile contextDirectory, String relativePath) {
String path = null;
if (contextDirectory != null) {
path = PathUtil.getLocalPath(contextDirectory);
@@ -136,7 +151,7 @@ public class FileUIUtils {
}
if (path != null) {
path = new File(path, "lib").getAbsolutePath();
path = new File(path, relativePath).getAbsolutePath();
}
else {
path = "";