aboutsummaryrefslogtreecommitdiff
path: root/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/ChooseConfigurationPage.java
diff options
context:
space:
mode:
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/ChooseConfigurationPage.java')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/ChooseConfigurationPage.java282
1 files changed, 282 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/ChooseConfigurationPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/ChooseConfigurationPage.java
new file mode 100644
index 000000000..1d6467e64
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/ChooseConfigurationPage.java
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
+ *
+ * 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.android.ide.eclipse.adt.internal.wizards.newxmlfile;
+
+import com.android.SdkConstants;
+import com.android.ide.common.resources.configuration.ResourceQualifier;
+import com.android.ide.eclipse.adt.AdtConstants;
+import com.android.ide.eclipse.adt.internal.ui.ConfigurationSelector;
+import com.android.ide.eclipse.adt.internal.ui.ConfigurationSelector.ConfigurationState;
+import com.android.ide.eclipse.adt.internal.ui.ConfigurationSelector.SelectorMode;
+import com.android.ide.eclipse.adt.internal.wizards.newxmlfile.NewXmlFileCreationPage.TypeInfo;
+import com.android.ide.eclipse.adt.internal.wizards.newxmlfile.NewXmlFileWizard.Values;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.wizard.IWizardPage;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Second page of the {@link NewXmlFileWizard}.
+ * <p>
+ * This page is used for choosing the current configuration or specific resource
+ * folder.
+ */
+public class ChooseConfigurationPage extends WizardPage {
+ private Values mValues;
+ private Text mWsFolderPathTextField;
+ private ConfigurationSelector mConfigSelector;
+ private boolean mInternalWsFolderPathUpdate;
+ private boolean mInternalConfigSelectorUpdate;
+
+ /** Absolute destination folder root, e.g. "/res/" */
+ static final String RES_FOLDER_ABS = AdtConstants.WS_RESOURCES + AdtConstants.WS_SEP;
+ /** Relative destination folder root, e.g. "res/" */
+ static final String RES_FOLDER_REL = SdkConstants.FD_RESOURCES + AdtConstants.WS_SEP;
+
+ /**
+ * Create the wizard.
+ *
+ * @param values value object holding current wizard state
+ */
+ public ChooseConfigurationPage(NewXmlFileWizard.Values values) {
+ super("chooseConfig");
+ mValues = values;
+ setTitle("Choose Configuration Folder");
+ }
+
+ @Override
+ public void setVisible(boolean visible) {
+ super.setVisible(visible);
+ if (visible) {
+ if (mValues.folderPath != null) {
+ mWsFolderPathTextField.setText(mValues.folderPath);
+ }
+ }
+ }
+
+ @Override
+ public void createControl(Composite parent) {
+ // This UI is maintained with WindowBuilder.
+
+ Composite composite = new Composite(parent, SWT.NULL);
+ composite.setLayout(new GridLayout(2, false /* makeColumnsEqualWidth */));
+ composite.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ // label before configuration selector
+ Label label = new Label(composite, SWT.NONE);
+ label.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1));
+ label.setText("Optional: Choose a specific configuration to limit the XML to:");
+
+ // configuration selector
+ mConfigSelector = new ConfigurationSelector(composite, SelectorMode.DEFAULT);
+ GridData gd = new GridData(GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL);
+ gd.verticalAlignment = SWT.FILL;
+ gd.horizontalAlignment = SWT.FILL;
+ gd.horizontalSpan = 2;
+ gd.heightHint = ConfigurationSelector.HEIGHT_HINT;
+ mConfigSelector.setLayoutData(gd);
+ mConfigSelector.setOnChangeListener(new ConfigurationChangeListener());
+
+ // Folder name: [text]
+ String tooltip = "The folder where the file will be generated, relative to the project.";
+
+ Label separator = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL);
+ GridData gdSeparator = new GridData(SWT.FILL, SWT.CENTER, false, false, 2, 1);
+ gdSeparator.heightHint = 10;
+ separator.setLayoutData(gdSeparator);
+ Label folderLabel = new Label(composite, SWT.NONE);
+ folderLabel.setText("Folder:");
+ folderLabel.setToolTipText(tooltip);
+
+ mWsFolderPathTextField = new Text(composite, SWT.BORDER);
+ mWsFolderPathTextField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ mWsFolderPathTextField.setToolTipText(tooltip);
+ mWsFolderPathTextField.addModifyListener(new ModifyListener() {
+ @Override
+ public void modifyText(ModifyEvent e) {
+ onWsFolderPathUpdated();
+ }
+ });
+
+ setControl(composite);
+
+ mConfigSelector.setConfiguration(mValues.configuration);
+ }
+
+ /**
+ * Callback called when the Folder text field is changed, either programmatically
+ * or by the user.
+ */
+ private void onWsFolderPathUpdated() {
+ if (mInternalWsFolderPathUpdate) {
+ return;
+ }
+
+ String wsFolderPath = mWsFolderPathTextField.getText();
+
+ // This is a custom path, we need to sanitize it.
+ // First it should start with "/res/". Then we need to make sure there are no
+ // relative paths, things like "../" or "./" or even "//".
+ wsFolderPath = wsFolderPath.replaceAll("/+\\.\\./+|/+\\./+|//+|\\\\+|^/+", "/"); //$NON-NLS-1$ //$NON-NLS-2$
+ wsFolderPath = wsFolderPath.replaceAll("^\\.\\./+|^\\./+", ""); //$NON-NLS-1$ //$NON-NLS-2$
+ wsFolderPath = wsFolderPath.replaceAll("/+\\.\\.$|/+\\.$|/+$", ""); //$NON-NLS-1$ //$NON-NLS-2$
+
+ // We get "res/foo" from selections relative to the project when we want a "/res/foo" path.
+ if (wsFolderPath.startsWith(RES_FOLDER_REL)) {
+ wsFolderPath = RES_FOLDER_ABS + wsFolderPath.substring(RES_FOLDER_REL.length());
+
+ mInternalWsFolderPathUpdate = true;
+ mWsFolderPathTextField.setText(wsFolderPath);
+ mInternalWsFolderPathUpdate = false;
+ }
+
+ mValues.folderPath = wsFolderPath;
+
+ if (wsFolderPath.startsWith(RES_FOLDER_ABS)) {
+ wsFolderPath = wsFolderPath.substring(RES_FOLDER_ABS.length());
+
+ int pos = wsFolderPath.indexOf(AdtConstants.WS_SEP_CHAR);
+ if (pos >= 0) {
+ wsFolderPath = wsFolderPath.substring(0, pos);
+ }
+
+ String[] folderSegments = wsFolderPath.split(SdkConstants.RES_QUALIFIER_SEP);
+
+ if (folderSegments.length > 0) {
+ String folderName = folderSegments[0];
+
+ // update config selector
+ mInternalConfigSelectorUpdate = true;
+ mConfigSelector.setConfiguration(folderSegments);
+ mInternalConfigSelectorUpdate = false;
+
+ IWizardPage previous = ((NewXmlFileWizard) getWizard()).getPreviousPage(this);
+ if (previous instanceof NewXmlFileCreationPage) {
+ NewXmlFileCreationPage p = (NewXmlFileCreationPage) previous;
+ p.selectTypeFromFolder(folderName);
+ }
+ }
+ }
+
+ validatePage();
+ }
+
+ /**
+ * Callback called when the configuration has changed in the {@link ConfigurationSelector}.
+ */
+ private class ConfigurationChangeListener implements Runnable {
+ @Override
+ public void run() {
+ if (mInternalConfigSelectorUpdate) {
+ return;
+ }
+
+ resetFolderPath(true /*validate*/);
+ }
+ }
+
+ /**
+ * Reset the current Folder path based on the UI selection
+ * @param validate if true, force a call to {@link #validatePage()}.
+ */
+ private void resetFolderPath(boolean validate) {
+ TypeInfo type = mValues.type;
+ if (type != null) {
+ mConfigSelector.getConfiguration(mValues.configuration);
+ StringBuilder sb = new StringBuilder(RES_FOLDER_ABS);
+ sb.append(mValues.configuration.getFolderName(type.getResFolderType()));
+
+ mInternalWsFolderPathUpdate = true;
+ String newPath = sb.toString();
+ mValues.folderPath = newPath;
+ mWsFolderPathTextField.setText(newPath);
+ mInternalWsFolderPathUpdate = false;
+
+ if (validate) {
+ validatePage();
+ }
+ }
+ }
+
+ /**
+ * Returns the destination folder path relative to the project or an empty string.
+ *
+ * @return the currently edited folder
+ */
+ public String getWsFolderPath() {
+ return mWsFolderPathTextField == null ? "" : mWsFolderPathTextField.getText(); //$NON-NLS-1$
+ }
+
+ /**
+ * Validates the fields, displays errors and warnings.
+ * Enables the finish button if there are no errors.
+ */
+ private void validatePage() {
+ String error = null;
+ String warning = null;
+
+ // -- validate folder configuration
+ if (error == null) {
+ ConfigurationState state = mConfigSelector.getState();
+ if (state == ConfigurationState.INVALID_CONFIG) {
+ ResourceQualifier qual = mConfigSelector.getInvalidQualifier();
+ if (qual != null) {
+ error =
+ String.format("The qualifier '%1$s' is invalid in the folder configuration.",
+ qual.getName());
+ }
+ } else if (state == ConfigurationState.REGION_WITHOUT_LANGUAGE) {
+ error = "The Region qualifier requires the Language qualifier.";
+ }
+ }
+
+ // -- validate generated path
+ if (error == null) {
+ String wsFolderPath = getWsFolderPath();
+ if (!wsFolderPath.startsWith(RES_FOLDER_ABS)) {
+ error = String.format("Target folder must start with %1$s.", RES_FOLDER_ABS);
+ }
+ }
+
+ // -- validate destination file doesn't exist
+ if (error == null) {
+ IFile file = mValues.getDestinationFile();
+ if (file != null && file.exists()) {
+ warning = "The destination file already exists";
+ }
+ }
+
+ // -- update UI & enable finish if there's no error
+ setPageComplete(error == null);
+ if (error != null) {
+ setMessage(error, IMessageProvider.ERROR);
+ } else if (warning != null) {
+ setMessage(warning, IMessageProvider.WARNING);
+ } else {
+ setErrorMessage(null);
+ setMessage(null);
+ }
+ }
+}