blob: 006830479db37098d6d3798317ea3ceb8f36773a [file] [log] [blame]
/*
* Copyright 2000-2012 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 com.intellij.ide.actions;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.util.ElementsChooser;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.components.ExportableComponent;
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.ui.DialogWrapper;
import com.intellij.openapi.ui.VerticalFlowLayout;
import com.intellij.openapi.util.AsyncResult;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.FieldPanel;
import com.intellij.util.Consumer;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.*;
import java.util.List;
public class ChooseComponentsToExportDialog extends DialogWrapper {
private static final Logger LOG = Logger.getInstance("#com.intellij.ide.actions.ChooseComponentsToExportDialog");
private final ElementsChooser<ComponentElementProperties> myChooser;
private final FieldPanel myPathPanel;
@NonNls
public static final String DEFAULT_PATH = FileUtil.toSystemDependentName(PathManager.getConfigPath()+"/"+"settings.jar");
private final boolean myShowFilePath;
private final String myDescription;
public ChooseComponentsToExportDialog(MultiMap<File, ExportableComponent> fileToComponents,
boolean showFilePath, final String title, String description) {
super(false);
myDescription = description;
myShowFilePath = showFilePath;
Map<ExportableComponent, ComponentElementProperties> componentToContainingListElement = new LinkedHashMap<ExportableComponent, ComponentElementProperties>();
for (ExportableComponent component : fileToComponents.values()) {
if (!addToExistingListElement(component, componentToContainingListElement, fileToComponents)) {
ComponentElementProperties componentElementProperties = new ComponentElementProperties();
componentElementProperties.addComponent(component);
componentToContainingListElement.put(component, componentElementProperties);
}
}
final Set<ComponentElementProperties> componentElementProperties = new LinkedHashSet<ComponentElementProperties>(componentToContainingListElement.values());
myChooser = new ElementsChooser<ComponentElementProperties>(true);
myChooser.setColorUnmarkedElements(false);
for (final ComponentElementProperties componentElementProperty : componentElementProperties) {
myChooser.addElement(componentElementProperty, true, componentElementProperty);
}
myChooser.sort(new Comparator<ComponentElementProperties>() {
@Override
public int compare(ComponentElementProperties o1,
ComponentElementProperties o2) {
return o1.toString().compareTo(o2.toString());
}
});
final ActionListener browseAction = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
chooseSettingsFile(myPathPanel.getText(), getWindow(), IdeBundle.message("title.export.file.location"), IdeBundle.message("prompt.choose.export.settings.file.path"))
.doWhenDone(new Consumer<String>() {
@Override
public void consume(String path) {
myPathPanel.setText(FileUtil.toSystemDependentName(path));
}
});
}
};
myPathPanel = new FieldPanel(IdeBundle.message("editbox.export.settings.to"), null, browseAction, null);
String exportPath = PropertiesComponent.getInstance().getOrInit("export.settings.path", DEFAULT_PATH);
myPathPanel.setText(exportPath);
myPathPanel.setChangeListener(new Runnable() {
@Override
public void run() {
updateControls();
}
});
updateControls();
setTitle(title);
init();
}
private void updateControls() {
setOKActionEnabled(!StringUtil.isEmptyOrSpaces(myPathPanel.getText()));
}
@NotNull
@Override
protected Action[] createLeftSideActions() {
AbstractAction selectAll = new AbstractAction("Select &All") {
@Override
public void actionPerformed(ActionEvent e) {
myChooser.setAllElementsMarked(true);
}
};
AbstractAction selectNone = new AbstractAction("Select &None") {
@Override
public void actionPerformed(ActionEvent e) {
myChooser.setAllElementsMarked(false);
}
};
AbstractAction invert = new AbstractAction("&Invert") {
@Override
public void actionPerformed(ActionEvent e) {
myChooser.invertSelection();
}
};
return new Action[]{selectAll, selectNone, invert};
}
@Override
protected void doOKAction() {
PropertiesComponent.getInstance().setValue("export.settings.path", myPathPanel.getText());
super.doOKAction();
}
private static boolean addToExistingListElement(ExportableComponent component,
Map<ExportableComponent, ComponentElementProperties> componentToContainingListElement,
MultiMap<File, ExportableComponent> fileToComponents) {
final File[] exportFiles = component.getExportFiles();
File file = null;
for (File exportFile : exportFiles) {
Collection<ExportableComponent> tiedComponents = fileToComponents.get(exportFile);
for (ExportableComponent tiedComponent : tiedComponents) {
if (tiedComponent == component) continue;
final ComponentElementProperties elementProperties = componentToContainingListElement.get(tiedComponent);
if (elementProperties != null && !FileUtil.filesEqual(exportFile, file)) {
LOG.assertTrue(file == null, "Component " + component + " serialize itself into " + file + " and " + exportFile);
// found
elementProperties.addComponent(component);
componentToContainingListElement.put(component, elementProperties);
file = exportFile;
}
}
}
return file != null;
}
@NotNull
public static AsyncResult<String> chooseSettingsFile(String oldPath, Component parent, final String title, final String description) {
FileChooserDescriptor chooserDescriptor = FileChooserDescriptorFactory.createSingleLocalFileDescriptor();
chooserDescriptor.setDescription(description);
chooserDescriptor.setHideIgnored(false);
chooserDescriptor.setTitle(title);
VirtualFile initialDir;
if (oldPath != null) {
final File oldFile = new File(oldPath);
initialDir = LocalFileSystem.getInstance().findFileByIoFile(oldFile);
if (initialDir == null && oldFile.getParentFile() != null) {
initialDir = LocalFileSystem.getInstance().findFileByIoFile(oldFile.getParentFile());
}
}
else {
initialDir = null;
}
final AsyncResult<String> result = new AsyncResult<String>();
FileChooser.chooseFiles(chooserDescriptor, null, parent, initialDir, new FileChooser.FileChooserConsumer() {
@Override
public void consume(List<VirtualFile> files) {
VirtualFile file = files.get(0);
if (file.isDirectory()) {
result.setDone(file.getPath() + '/' + new File(DEFAULT_PATH).getName());
}
else {
result.setDone(file.getPath());
}
}
@Override
public void cancelled() {
result.setRejected();
}
});
return result;
}
@Override
public JComponent getPreferredFocusedComponent() {
return myPathPanel.getTextField();
}
@Override
protected JComponent createNorthPanel() {
return new JLabel(myDescription);
}
@Override
protected JComponent createCenterPanel() {
return myChooser;
}
@Override
protected JComponent createSouthPanel() {
final JComponent buttons = super.createSouthPanel();
if (!myShowFilePath) return buttons;
final JPanel panel = new JPanel(new VerticalFlowLayout());
panel.add(myPathPanel);
panel.add(buttons);
return panel;
}
Set<ExportableComponent> getExportableComponents() {
final List<ComponentElementProperties> markedElements = myChooser.getMarkedElements();
final Set<ExportableComponent> components = new HashSet<ExportableComponent>();
for (ComponentElementProperties elementProperties : markedElements) {
components.addAll(elementProperties.myComponents);
}
return components;
}
private static class ComponentElementProperties implements ElementsChooser.ElementProperties {
private final Set<ExportableComponent> myComponents = new HashSet<ExportableComponent>();
private boolean addComponent(ExportableComponent component) {
return myComponents.add(component);
}
@Override
@Nullable
public Icon getIcon() {
return null;
}
@Override
@Nullable
public Color getColor() {
return null;
}
public String toString() {
Set<String> names = new LinkedHashSet<String>();
for (final ExportableComponent component : myComponents) {
names.add(component.getPresentableName());
}
return StringUtil.join(names.toArray(new String[names.size()]), ", ");
}
}
File getExportFile() {
return new File(myPathPanel.getText());
}
@Override
protected String getDimensionServiceKey() {
return "#com.intellij.ide.actions.ChooseComponentsToExportDialog";
}
}