use rich CreateResourceFile dialog when extracting layout

This commit is contained in:
Eugene Kudelevsky
2012-08-21 16:25:14 +04:00
parent 58c7f8a166
commit 9a5cb4776d
8 changed files with 74 additions and 102 deletions
@@ -245,7 +245,7 @@ public class ResourceDialog extends DialogWrapper implements TreeSelectionListen
private void createNewResourceFile(ResourceType resourceType) {
AndroidFacet facet = AndroidFacet.getInstance(myModule);
XmlFile newFile = CreateResourceFileAction.createFileResource(facet, resourceType, null, true);
XmlFile newFile = CreateResourceFileAction.createFileResource(facet, resourceType, null, null, null, true);
if (newFile != null) {
String name = newFile.getName();
@@ -59,7 +59,7 @@ public abstract class CreateResourceDirectoryDialog extends DialogWrapper {
}
});
myDeviceConfiguratorPanel = new DeviceConfiguratorPanel(null) {
myDeviceConfiguratorPanel = new DeviceConfiguratorPanel() {
@Override
public void applyEditors() {
try {
@@ -17,6 +17,7 @@
package org.jetbrains.android.actions;
import com.android.AndroidConstants;
import com.android.ide.common.resources.configuration.FolderConfiguration;
import com.android.resources.ResourceType;
import com.intellij.CommonBundle;
import com.intellij.ide.actions.CreateElementActionBase;
@@ -96,8 +97,11 @@ public class CreateResourceFileAction extends CreateElementActionBase {
public static XmlFile createFileResource(@NotNull AndroidFacet facet,
@NotNull final ResourceType resType,
@Nullable String resName,
@Nullable String rootElement,
@Nullable FolderConfiguration config,
boolean chooseResName) {
final PsiElement[] elements = doCreateFileResource(facet, resType, resName, chooseResName);
final PsiElement[] elements = doCreateFileResource(facet, resType, resName, rootElement,
config, chooseResName);
if (elements.length == 0) {
return null;
}
@@ -109,6 +113,8 @@ public class CreateResourceFileAction extends CreateElementActionBase {
private static PsiElement[] doCreateFileResource(@NotNull AndroidFacet facet,
@NotNull final ResourceType resType,
@Nullable String resName,
@Nullable String rootElement,
@Nullable FolderConfiguration config,
boolean chooseResName) {
final CreateResourceFileAction action = getInstance();
@@ -119,8 +125,8 @@ public class CreateResourceFileAction extends CreateElementActionBase {
selectedModule = facet.getModule();
}
else {
final MyDialog dialog =
new MyDialog(facet, action.mySubactions.values(), resType, resName, chooseResName, action, facet.getModule(), true);
final MyDialog dialog = new MyDialog(facet, action.mySubactions.values(), resType, resName, rootElement,
config, chooseResName, action, facet.getModule(), true);
dialog.show();
if (!dialog.isOK()) {
return PsiElement.EMPTY_ARRAY;
@@ -165,7 +171,7 @@ public class CreateResourceFileAction extends CreateElementActionBase {
LOG.assertTrue(facet != null);
final MyDialog dialog =
new MyDialog(facet, mySubactions.values(), null, null, true, CreateResourceFileAction.this, facet.getModule(), false) {
new MyDialog(facet, mySubactions.values(), null, null, null, null, true, CreateResourceFileAction.this, facet.getModule(), false) {
@Override
protected InputValidator createValidator(@NotNull String subdirName) {
return CreateResourceFileAction.this.createValidator(project, directory, subdirName);
@@ -240,11 +246,14 @@ public class CreateResourceFileAction extends CreateElementActionBase {
Collection<CreateTypedResourceFileAction> actions,
@Nullable ResourceType predefinedResourceType,
@Nullable String predefinedFileName,
@Nullable String predefinedRootElement,
@Nullable FolderConfiguration predefinedConfig,
boolean chooseFileName,
@NotNull CreateResourceFileAction action,
@NotNull Module module,
boolean chooseModule) {
super(facet, actions, predefinedResourceType, predefinedFileName, chooseFileName, module, chooseModule);
super(facet, actions, predefinedResourceType, predefinedFileName, predefinedRootElement,
predefinedConfig, chooseFileName, module, chooseModule);
myAction = action;
}
@@ -80,6 +80,8 @@ public class CreateResourceFileDialog extends DialogWrapper {
Collection<CreateTypedResourceFileAction> actions,
@Nullable ResourceType predefinedResourceType,
@Nullable String predefinedFileName,
@Nullable String predefinedRootElement,
@Nullable FolderConfiguration predefinedConfig,
boolean chooseFileName,
@NotNull Module module,
boolean chooseModule) {
@@ -111,7 +113,7 @@ public class CreateResourceFileDialog extends DialogWrapper {
}
}
myDeviceConfiguratorPanel = new DeviceConfiguratorPanel(null) {
myDeviceConfiguratorPanel = new DeviceConfiguratorPanel() {
@Override
public void applyEditors() {
try {
@@ -137,6 +139,9 @@ public class CreateResourceFileDialog extends DialogWrapper {
setOKActionEnabled(myDirectoryNameTextField.getText().length() > 0);
}
};
if (predefinedConfig != null) {
myDeviceConfiguratorPanel.init(predefinedConfig);
}
myResourceTypeCombo.getComboBox().addActionListener(new ActionListener() {
@Override
@@ -191,6 +196,12 @@ public class CreateResourceFileDialog extends DialogWrapper {
myDeviceConfiguratorWrapper.add(myDeviceConfiguratorPanel, BorderLayout.CENTER);
setOKActionEnabled(myDirectoryNameTextField.getText().length() > 0);
updateRootElementTextField();
if (predefinedRootElement != null) {
myRootElementLabel.setVisible(false);
myRootElementFieldWrapper.setVisible(false);
myRootElementField.setText(predefinedRootElement);
}
init();
setTitle(AndroidBundle.message("new.resource.dialog.title"));
@@ -74,7 +74,7 @@ public class CreateFileResourceQuickFix implements LocalQuickFix, IntentionActio
@Override
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
final XmlFile newFile =
CreateResourceFileAction.createFileResource(myFacet, myResourceType, myResourceName + ".xml", myChooseResName);
CreateResourceFileAction.createFileResource(myFacet, myResourceType, myResourceName + ".xml", null, null, myChooseResName);
if (newFile != null) {
UndoUtil.markPsiFileForUndo(myFile);
}
@@ -1,12 +1,13 @@
package org.jetbrains.android.refactoring;
import com.android.AndroidConstants;
import com.android.ide.common.resources.configuration.FolderConfiguration;
import com.android.resources.ResourceType;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.command.UndoConfirmationPolicy;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.InputValidatorEx;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.psi.*;
@@ -15,16 +16,14 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.HashSet;
import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.DomManager;
import org.jetbrains.android.actions.CreateResourceFileAction;
import org.jetbrains.android.dom.layout.Include;
import org.jetbrains.android.dom.layout.LayoutViewElement;
import org.jetbrains.android.facet.AndroidFacet;
import org.jetbrains.android.util.AndroidBundle;
import org.jetbrains.android.util.AndroidCommonUtils;
import org.jetbrains.android.util.AndroidUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -42,6 +41,7 @@ public class AndroidExtractAsIncludeAction extends AndroidBaseLayoutRefactoringA
private final MyTestConfig myTestConfig;
@SuppressWarnings("UnusedDeclaration")
public AndroidExtractAsIncludeAction() {
myTestConfig = null;
}
@@ -134,57 +134,40 @@ public class AndroidExtractAsIncludeAction extends AndroidBaseLayoutRefactoringA
final List<XmlTag> tagsInRange = collectAllTags(from, to);
assert tagsInRange.size() > 0 : "there is no tag inside the range";
final String fileName = myTestConfig != null ? myTestConfig.myLayoutFileName : null;
final String dirName = dir.getName();
final FolderConfiguration config = dirName.length() > 0
? FolderConfiguration.getConfig(dirName.split(AndroidConstants.RES_QUALIFIER_SEP))
: null;
final String title = AndroidBundle.message("android.extract.as.include.title");
final String fileName;
if (myTestConfig != null) {
fileName = myTestConfig.myLayoutFileName;
}
else {
fileName = Messages.showInputDialog(project, "Enter new layout file name", title, Messages.getQuestionIcon(),
null, new MyInputValidatorEx(dir));
}
if (fileName == null) {
return;
}
final String fileName1 = addXmlExtensionIfNecessary(fileName);
new WriteCommandAction.Simple(project, "Extract '" + fileName1 + "' layout", file) {
CommandProcessor.getInstance().executeCommand(project, new Runnable() {
@Override
protected void run() throws Throwable {
doRefactor(project, file, from, to, dir, parentTag, fileName1, tagsInRange.size() > 1);
}
public void run() {
final XmlFile newFile =
CreateResourceFileAction.createFileResource(facet, ResourceType.LAYOUT, fileName, "temp_root", config, true);
@Override
protected UndoConfirmationPolicy getUndoConfirmationPolicy() {
return UndoConfirmationPolicy.REQUEST_CONFIRMATION;
if (newFile != null) {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
doRefactor(facet, file, newFile, from, to, parentTag, tagsInRange.size() > 1);
}
});
}
}
}.execute();
}, "Extract Android Layout", null, UndoConfirmationPolicy.REQUEST_CONFIRMATION);
}
private static void doRefactor(Project project,
private static void doRefactor(AndroidFacet facet,
PsiFile file,
XmlFile newFile,
PsiElement from,
PsiElement to,
PsiDirectory dir,
XmlTag parentTag,
String fileName,
boolean wrapWithMerge) {
final Project project = facet.getModule().getProject();
final String textToExtract = file.getText().substring(from.getTextRange().getStartOffset(),
to.getTextRange().getEndOffset());
final XmlFile newFile;
try {
final PsiFile f = dir.createFile(fileName);
assert f instanceof XmlFile;
newFile = (XmlFile)f;
}
catch (Exception e) {
AndroidUtils.reportError(project, e.getClass().getName() + ": " + e.getMessage(),
AndroidBundle.message("android.extract.as.include.title"));
return;
}
final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project);
final Document document = documentManager.getDocument(newFile);
assert document != null;
@@ -236,7 +219,7 @@ public class AndroidExtractAsIncludeAction extends AndroidBaseLayoutRefactoringA
}
}
}
final String resourceName = AndroidCommonUtils.getResourceName(ResourceType.LAYOUT.getName(), fileName);
final String resourceName = AndroidCommonUtils.getResourceName(ResourceType.LAYOUT.getName(), newFile.getName());
final XmlTag includeTag = elementFactory.createTagFromText("<include layout=\"@layout/" + resourceName + "\"/>");
parentTag.addAfter(includeTag, to);
parentTag.deleteChildRange(from, to);
@@ -306,38 +289,4 @@ public class AndroidExtractAsIncludeAction extends AndroidBaseLayoutRefactoringA
myLayoutFileName = layoutFileName;
}
}
private static class MyInputValidatorEx implements InputValidatorEx {
private final PsiDirectory myDirectory;
public MyInputValidatorEx(@NotNull PsiDirectory directory) {
myDirectory = directory;
}
@Nullable
@Override
public String getErrorText(String inputString) {
if (inputString.length() == 0) {
return null;
}
final String fileName = addXmlExtensionIfNecessary(inputString);
try {
myDirectory.checkCreateFile(fileName);
}
catch (IncorrectOperationException e) {
return e.getMessage();
}
return null;
}
@Override
public boolean checkInput(String inputString) {
return inputString.length() > 0;
}
@Override
public boolean canClose(String inputString) {
return checkInput(inputString) && getErrorText(inputString) == null;
}
}
}
@@ -70,7 +70,7 @@ public abstract class DeviceConfiguratorPanel extends JPanel {
};
@SuppressWarnings("unchecked")
public DeviceConfiguratorPanel(FolderConfiguration config) {
public DeviceConfiguratorPanel() {
super(new BorderLayout());
createUIComponents();
@@ -148,18 +148,6 @@ public abstract class DeviceConfiguratorPanel extends JPanel {
myQualifierOptionsPanel.add(editor.getComponent(), name);
}
if (config != null) {
myChosenQualifiersConfig.set(config);
myAvailableQualifiersConfig.substract(config);
for (ResourceQualifier qualifier : config.getQualifiers()) {
final MyQualifierEditor editor = myEditors.get(qualifier.getShortName());
if (editor != null) {
editor.reset(qualifier);
}
}
}
myAvailableQualifiersList.setCellRenderer(new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
@@ -239,6 +227,18 @@ public abstract class DeviceConfiguratorPanel extends JPanel {
});
}
public void init(@NotNull FolderConfiguration config) {
myChosenQualifiersConfig.set(config);
myAvailableQualifiersConfig.substract(config);
for (ResourceQualifier qualifier : config.getQualifiers()) {
final MyQualifierEditor editor = myEditors.get(qualifier.getShortName());
if (editor != null) {
editor.reset(qualifier);
}
}
}
protected void createDefaultConfig(FolderConfiguration config) {
config.createDefault();
}
@@ -50,7 +50,7 @@ public class EditConfigurationDialog extends DialogWrapper {
myEditDeviceForm.reset(device);
}
myDeviceConfiguratorPanel = new DeviceConfiguratorPanel(config) {
myDeviceConfiguratorPanel = new DeviceConfiguratorPanel() {
@Override
public void applyEditors() {
try {
@@ -84,6 +84,9 @@ public class EditConfigurationDialog extends DialogWrapper {
config.setRegionQualifier(null);
}
};
if (config != null) {
myDeviceConfiguratorPanel.init(config);
}
myDeviceConfiguratorPanelWrapper.add(myDeviceConfiguratorPanel, BorderLayout.CENTER);
myEditDeviceForm.getNameField().getDocument().addDocumentListener(myDeviceConfiguratorPanel.getUpdatingDocumentListener());