aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigEditDialog.java356
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigManagerDialog.java566
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigurationComposite.java424
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/OrientationMenuAction.java26
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java37
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.base/.classpath1
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.base/META-INF/MANIFEST.MF5
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.base/build.properties3
-rwxr-xr-xeclipse/scripts/create_all_symlinks.sh2
-rw-r--r--ide_common/src/com/android/ide/common/resources/configuration/DeviceConfigHelper.java11
-rw-r--r--sdkmanager/libs/sdklib/src/com/android/sdklib/devices/DeviceWriter.java1
-rwxr-xr-xsdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/AvdInfo.java18
-rw-r--r--sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/AvdManager.java9
-rw-r--r--sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdCreationDialog.java65
14 files changed, 353 insertions, 1171 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigEditDialog.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigEditDialog.java
deleted file mode 100644
index bd45400..0000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigEditDialog.java
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * Copyright (C) 2009 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.editors.layout.configuration;
-
-import com.android.ide.common.resources.configuration.FolderConfiguration;
-import com.android.ide.common.resources.configuration.LanguageQualifier;
-import com.android.ide.common.resources.configuration.NightModeQualifier;
-import com.android.ide.common.resources.configuration.RegionQualifier;
-import com.android.ide.common.resources.configuration.ResourceQualifier;
-import com.android.ide.common.resources.configuration.UiModeQualifier;
-import com.android.ide.common.resources.configuration.VersionQualifier;
-import com.android.ide.eclipse.adt.internal.editors.IconFactory;
-import com.android.ide.eclipse.adt.internal.sdk.LayoutDevice;
-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.IQualifierFilter;
-import com.android.ide.eclipse.adt.internal.ui.ConfigurationSelector.SelectorMode;
-import com.android.sdkuilib.ui.GridDialog;
-
-import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.VerifyEvent;
-import org.eclipse.swt.events.VerifyListener;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Group;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
-
-import java.text.DecimalFormat;
-import java.text.DecimalFormatSymbols;
-import java.text.ParseException;
-import java.util.regex.Pattern;
-
-/**
- * Dialog to edit both a {@link LayoutDevice}, and a {@link FolderConfiguration} at the same time.
- */
-public class ConfigEditDialog extends GridDialog {
-
- private static final Pattern FLOAT_PATTERN;
- static {
- // get the decimal separator char
- DecimalFormatSymbols dfs = new DecimalFormatSymbols();
-
- // make a pattern that's basically ##.# where .# is optional and where . can be . or ,
- // depending on the locale
- FLOAT_PATTERN = Pattern.compile(
- "\\d*(" + //$NON-NLS-1$
- Pattern.quote(new String(new char[] { dfs.getDecimalSeparator() })) +
- "\\d?)?"); //$NON-NLS-1$
- }
-
- private final FolderConfiguration mConfig = new FolderConfiguration();
-
- private ConfigurationSelector mConfigSelector;
- private Composite mStatusComposite;
- private Label mStatusLabel;
- private Label mStatusImage;
-
- private Image mError;
-
- private String mDeviceName;
- private String mConfigName;
- private float mXDpi = Float.NaN;
- private float mYDpi = Float.NaN;
-
- private final DecimalFormat mDecimalFormat = new DecimalFormat();
-
-
- public ConfigEditDialog(Shell parentShell, FolderConfiguration config) {
- super(parentShell, 1, false);
- mConfig.set(config);
- }
-
- public void setDeviceName(String name) {
- mDeviceName = name;
- }
-
- public String getDeviceName() {
- return mDeviceName;
- }
-
- public void setXDpi(float xdpi) {
- mXDpi = xdpi;
- }
-
- public float getXDpi() {
- return mXDpi;
- }
-
- public void setYDpi(float ydpi) {
- mYDpi = ydpi;
- }
-
- public float getYDpi() {
- return mYDpi;
- }
-
- public void setConfigName(String name) {
- mConfigName = name;
- }
-
- public String getConfigName() {
- return mConfigName;
- }
-
- public void setConfig(FolderConfiguration config) {
- mConfig.set(config);
- }
-
- public void getConfig(FolderConfiguration config) {
- config.set(mConfig);
- config.updateScreenWidthAndHeight();
- }
-
- @Override
- public void createDialogContent(Composite parent) {
- mError = IconFactory.getInstance().getIcon("error"); //$NON-NLS-1$
-
- Group deviceGroup = new Group(parent, SWT.NONE);
- deviceGroup.setText("Device");
- deviceGroup.setLayoutData(new GridData(GridData.FILL_BOTH));
- deviceGroup.setLayout(new GridLayout(2, false));
-
- Label l = new Label(deviceGroup, SWT.None);
- l.setText("Name");
-
- final Text deviceNameText = new Text(deviceGroup, SWT.BORDER);
- deviceNameText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
- if (mDeviceName != null) {
- deviceNameText.setText(mDeviceName);
- }
- deviceNameText.addModifyListener(new ModifyListener() {
- @Override
- public void modifyText(ModifyEvent e) {
- mDeviceName = deviceNameText.getText().trim();
- validateOk();
- }
- });
-
-
- VerifyListener floatVerifier = new VerifyListener() {
- @Override
- public void verifyText(VerifyEvent event) {
- // combine the current content and the new text
- String text = ((Text)event.widget).getText();
- text = text.substring(0, event.start) + event.text + text.substring(event.end);
-
- // now make sure it's a match for the regex
- event.doit = FLOAT_PATTERN.matcher(text).matches();
- }
- };
-
- l = new Label(deviceGroup, SWT.None);
- l.setText("x dpi");
-
- final Text deviceXDpiText = new Text(deviceGroup, SWT.BORDER);
- deviceXDpiText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
- if (Float.isNaN(mXDpi) == false) {
- deviceXDpiText.setText(String.format("%.1f", mXDpi)); //$NON-NLS-1$
- }
- deviceXDpiText.addVerifyListener(floatVerifier);
- deviceXDpiText.addModifyListener(new ModifyListener() {
- @Override
- public void modifyText(ModifyEvent e) {
- String value = deviceXDpiText.getText();
- if (value.length() == 0) {
- mXDpi = Float.NaN;
- } else {
- try {
- mXDpi = mDecimalFormat.parse(value).floatValue();
- } catch (ParseException exception) {
- mXDpi = Float.NaN;
- }
- }
- }
- });
-
- l = new Label(deviceGroup, SWT.None);
- l.setText("y dpi");
-
- final Text deviceYDpiText = new Text(deviceGroup, SWT.BORDER);
- deviceYDpiText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
- if (Float.isNaN(mYDpi) == false) {
- deviceYDpiText.setText(String.format("%.1f", mYDpi)); //$NON-NLS-1$
- }
- deviceYDpiText.addVerifyListener(floatVerifier);
- deviceYDpiText.addModifyListener(new ModifyListener() {
- @Override
- public void modifyText(ModifyEvent e) {
- String value = deviceYDpiText.getText();
- if (value.length() == 0) {
- mYDpi = Float.NaN;
- } else {
- try {
- mYDpi = mDecimalFormat.parse(value).floatValue();
- } catch (ParseException exception) {
- mYDpi = Float.NaN;
- }
- }
- }
- });
-
- Group configGroup = new Group(parent, SWT.NONE);
- configGroup.setText("Configuration");
- configGroup.setLayoutData(new GridData(GridData.FILL_BOTH));
- configGroup.setLayout(new GridLayout(2, false));
-
- l = new Label(configGroup, SWT.None);
- l.setText("Name");
-
- final Text configNameText = new Text(configGroup, SWT.BORDER);
- configNameText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
- if (mConfigName != null) {
- configNameText.setText(mConfigName);
- }
- configNameText.addModifyListener(new ModifyListener() {
- @Override
- public void modifyText(ModifyEvent e) {
- mConfigName = configNameText.getText().trim();
- validateOk();
- }
- });
-
- mConfigSelector = new ConfigurationSelector(configGroup, SelectorMode.DEVICE_ONLY);
- // configure the selector to be in "device mode" and not accept language/region/version
- // since those are selected from a different combo
- // FIXME: add version combo.
- mConfigSelector.setQualifierFilter(new IQualifierFilter() {
- @Override
- public boolean accept(ResourceQualifier qualifier) {
- if (qualifier instanceof LanguageQualifier ||
- qualifier instanceof RegionQualifier ||
- qualifier instanceof UiModeQualifier ||
- qualifier instanceof NightModeQualifier ||
- qualifier instanceof VersionQualifier) {
- return false;
- }
-
- return true;
- }
- });
- mConfigSelector.setConfiguration(mConfig);
- GridData gd;
- mConfigSelector.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
- gd.horizontalSpan = 2;
- gd.widthHint = ConfigurationSelector.WIDTH_HINT;
- gd.heightHint = ConfigurationSelector.HEIGHT_HINT;
-
- // add a listener to check on the validity of the FolderConfiguration as
- // they are built.
- mConfigSelector.setOnChangeListener(new Runnable() {
- @Override
- public void run() {
- if (mConfigSelector.getState() == ConfigurationState.OK) {
- mConfigSelector.getConfiguration(mConfig);
- }
-
- validateOk();
- }
- });
-
- mStatusComposite = new Composite(parent, SWT.NONE);
- mStatusComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
- GridLayout gl = new GridLayout(2, false);
- mStatusComposite.setLayout(gl);
- gl.marginHeight = gl.marginWidth = 0;
-
- mStatusImage = new Label(mStatusComposite, SWT.NONE);
- mStatusLabel = new Label(mStatusComposite, SWT.NONE);
- mStatusLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
- resetStatus();
- }
-
- @Override
- protected Control createContents(Composite parent) {
- Control c = super.createContents(parent);
- validateOk();
- return c;
- }
-
- /**
- * resets the status label to show the file that will be created.
- */
- private void resetStatus() {
- String displayString = Dialog.shortenText(
- String.format("Config: %1$s", mConfig.toString()),
- mStatusLabel);
- mStatusLabel.setText(displayString);
- }
-
- private void setError(String text) {
- String displayString = Dialog.shortenText(text, mStatusLabel);
- mStatusLabel.setText(displayString);
- mStatusImage.setImage(mError);
- getButton(IDialogConstants.OK_ID).setEnabled(false);
- }
-
- private void validateOk() {
- // check the device name
- if (mDeviceName == null || mDeviceName.length() == 0) {
- setError("Device name must not be empty");
- return;
- }
-
- // check the config name
- if (mConfigName == null || mConfigName.length() == 0) {
- setError("Configuration name must not be empty");
- return;
- }
-
- // and check the config itself
- ConfigurationState state = mConfigSelector.getState();
-
- switch (state) {
- case INVALID_CONFIG:
- ResourceQualifier invalidQualifier = mConfigSelector.getInvalidQualifier();
- setError(String.format(
- "Invalid Configuration: %1$s has no filter set.",
- invalidQualifier.getName()));
- return;
- case REGION_WITHOUT_LANGUAGE:
- setError("The Region qualifier requires the Language qualifier.");
- return;
- }
-
- // no error
- mStatusImage.setImage(null);
- resetStatus();
- getButton(IDialogConstants.OK_ID).setEnabled(true);
-
- // need to relayout, because of the change in size in mErrorImage.
- mStatusComposite.layout();
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigManagerDialog.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigManagerDialog.java
deleted file mode 100644
index 2adefa7..0000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigManagerDialog.java
+++ /dev/null
@@ -1,566 +0,0 @@
-/*
- * Copyright (C) 2009 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.editors.layout.configuration;
-
-import com.android.ddmuilib.TableHelper;
-import com.android.ide.common.resources.configuration.FolderConfiguration;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.sdk.LayoutDevice;
-import com.android.ide.eclipse.adt.internal.sdk.LayoutDevice.DeviceConfig;
-import com.android.ide.eclipse.adt.internal.sdk.LayoutDeviceManager;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.sdkuilib.ui.GridDialog;
-
-import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.jface.viewers.ILabelProviderListener;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.ITableLabelProvider;
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.jface.viewers.TreePath;
-import org.eclipse.jface.viewers.TreeSelection;
-import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.jface.window.Window;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Tree;
-
-import java.util.List;
-
-/**
- * Dialog to view the layout devices with action button to create/edit/delete/copy layout devices
- * and configs.
- *
- */
-public class ConfigManagerDialog extends GridDialog {
-
- private final static String COL_NAME = AdtPlugin.PLUGIN_ID + ".configmanager.name"; //$NON-NLS-1$
- private final static String COL_CONFIG = AdtPlugin.PLUGIN_ID + ".configmanager.config"; //$NON-NLS-1$
-
- /**
- * enum to represent the different origin of the layout devices.
- */
- private static enum DeviceType {
- DEFAULT("Default"),
- ADDON("Add-on"),
- CUSTOM("Custom");
-
- private final String mDisplay;
-
- DeviceType(String display) {
- mDisplay = display;
- }
-
- String getDisplayString() {
- return mDisplay;
- }
- }
-
- /**
- * simple class representing the tree selection with the proper types.
- */
- private static class DeviceSelection {
- public DeviceSelection(DeviceType type, LayoutDevice device,
- DeviceConfig config) {
- this.type = type;
- this.device = device;
- this.config = config;
- }
-
- final DeviceType type;
- final LayoutDevice device;
- final DeviceConfig config;
- }
-
- private final LayoutDeviceManager mManager;
-
- private TreeViewer mTreeViewer;
- private Button mNewButton;
- private Button mEditButton;
- private Button mCopyButton;
- private Button mDeleteButton;
-
- /**
- * Content provider of the {@link TreeViewer}. The expected input is
- * {@link LayoutDeviceManager}.
- *
- */
- private final static class DeviceContentProvider implements ITreeContentProvider {
- private final static DeviceType[] sCategory = new DeviceType[] {
- DeviceType.DEFAULT, DeviceType.ADDON, DeviceType.CUSTOM
- };
-
- private LayoutDeviceManager mLayoutDeviceManager;
-
- public DeviceContentProvider() {
- }
-
- @Override
- public Object[] getElements(Object inputElement) {
- return sCategory;
- }
-
- @Override
- public Object[] getChildren(Object parentElement) {
- if (parentElement instanceof DeviceType) {
- if (DeviceType.DEFAULT.equals(parentElement)) {
- return mLayoutDeviceManager.getDefaultLayoutDevices().toArray();
- } else if (DeviceType.ADDON.equals(parentElement)) {
- return mLayoutDeviceManager.getAddOnLayoutDevice().toArray();
- } else if (DeviceType.CUSTOM.equals(parentElement)) {
- return mLayoutDeviceManager.getUserLayoutDevices().toArray();
- }
- } else if (parentElement instanceof LayoutDevice) {
- LayoutDevice device = (LayoutDevice)parentElement;
- return device.getConfigs().toArray();
- }
-
- return null;
- }
-
- @Override
- public Object getParent(Object element) {
- // parent cannot be computed. this is fine.
- return null;
- }
-
- @Override
- public boolean hasChildren(Object element) {
- if (element instanceof DeviceType) {
- if (DeviceType.DEFAULT.equals(element)) {
- return mLayoutDeviceManager.getDefaultLayoutDevices().size() > 0;
- } else if (DeviceType.ADDON.equals(element)) {
- return mLayoutDeviceManager.getAddOnLayoutDevice().size() > 0;
- } else if (DeviceType.CUSTOM.equals(element)) {
- return mLayoutDeviceManager.getUserLayoutDevices().size() > 0;
- }
- } else if (element instanceof LayoutDevice) {
- LayoutDevice device = (LayoutDevice)element;
- return device.getConfigs().size() > 0;
- }
-
- return false;
- }
-
-
- @Override
- public void dispose() {
- // nothing to dispose
- }
-
- @Override
- public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
- if (newInput instanceof LayoutDeviceManager) {
- mLayoutDeviceManager = (LayoutDeviceManager)newInput;
- return;
- }
-
- // when the dialog closes we get null input
- if (newInput != null) {
- throw new IllegalArgumentException(
- "ConfigContentProvider requires input to be LayoutDeviceManager");
- }
- }
- }
-
- /**
- * Label provider for the {@link TreeViewer}.
- * Supported elements are {@link DeviceType}, {@link LayoutDevice}, and {@link DeviceConfig}.
- *
- */
- private final static class DeviceLabelProvider implements ITableLabelProvider {
-
- @Override
- public String getColumnText(Object element, int columnIndex) {
- if (element instanceof DeviceType) {
- if (columnIndex == 0) {
- return ((DeviceType)element).getDisplayString();
- }
- } else if (element instanceof LayoutDevice) {
- if (columnIndex == 0) {
- return ((LayoutDevice)element).getName();
- }
- } else if (element instanceof DeviceConfig) {
- if (columnIndex == 0) {
- return ((DeviceConfig)element).getName();
- } else {
- return ((DeviceConfig)element).getConfig().toString();
- }
- }
- return null;
- }
-
- @Override
- public Image getColumnImage(Object element, int columnIndex) {
- // no image
- return null;
- }
-
- @Override
- public void addListener(ILabelProviderListener listener) {
- // no listener
- }
-
- @Override
- public void removeListener(ILabelProviderListener listener) {
- // no listener
- }
-
- @Override
- public void dispose() {
- // nothing to dispose
- }
-
- @Override
- public boolean isLabelProperty(Object element, String property) {
- return false;
- }
- }
-
- protected ConfigManagerDialog(Shell parentShell) {
- super(parentShell, 2, false);
- mManager = Sdk.getCurrent().getLayoutDeviceManager();
- }
-
- @Override
- protected int getShellStyle() {
- return super.getShellStyle() | SWT.RESIZE;
- }
-
- @Override
- protected void configureShell(Shell newShell) {
- super.configureShell(newShell);
- newShell.setText("Device Configurations");
- }
-
- @Override
- public void createDialogContent(final Composite parent) {
- GridData gd;
- GridLayout gl;
-
- Tree tree = new Tree(parent, SWT.SINGLE | SWT.FULL_SELECTION);
- tree.setLayoutData(gd = new GridData(GridData.FILL_BOTH));
- gd.widthHint = 700;
-
- tree.setHeaderVisible(true);
- tree.setLinesVisible(true);
- TableHelper.createTreeColumn(tree, "Name", SWT.LEFT, 150, COL_NAME,
- AdtPlugin.getDefault().getPreferenceStore());
- TableHelper.createTreeColumn(tree, "Configuration", SWT.LEFT, 500, COL_CONFIG,
- AdtPlugin.getDefault().getPreferenceStore());
-
- mTreeViewer = new TreeViewer(tree);
- mTreeViewer.setContentProvider(new DeviceContentProvider());
- mTreeViewer.setLabelProvider(new DeviceLabelProvider());
- mTreeViewer.setAutoExpandLevel(TreeViewer.ALL_LEVELS);
- mTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
- @Override
- public void selectionChanged(SelectionChangedEvent event) {
- setEnabled(getSelection());
- }
- });
-
- Composite buttons = new Composite(parent, SWT.NONE);
- buttons.setLayoutData(new GridData(GridData.FILL_VERTICAL));
- buttons.setLayout(gl = new GridLayout());
- gl.marginHeight = gl.marginWidth = 0;
-
- mNewButton = new Button(buttons, SWT.PUSH | SWT.FLAT);
- mNewButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
- mNewButton.setText("New...");
- mNewButton.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- DeviceSelection selection = getSelection();
-
- ConfigEditDialog dlg = new ConfigEditDialog(parent.getShell(), null);
- if (selection.device != null) {
- dlg.setDeviceName(selection.device.getName());
- dlg.setXDpi(selection.device.getXDpi());
- dlg.setYDpi(selection.device.getYDpi());
- }
- if (selection.config != null) {
- dlg.setConfigName(selection.config.getName());
- dlg.setConfig(selection.config.getConfig());
- }
-
- if (dlg.open() == Window.OK) {
- String deviceName = dlg.getDeviceName();
- String configName = dlg.getConfigName();
- FolderConfiguration config = new FolderConfiguration();
- dlg.getConfig(config);
-
- // first if there was no original device, we create one.
- // Because the new button is disabled when something else than "custom" is
- // selected, we always add to the user devices without checking.
- LayoutDevice d;
- if (selection.device == null) {
- // FIXME: this doesn't check if the device name is taken.
- d = mManager.addUserDevice(deviceName, dlg.getXDpi(), dlg.getYDpi());
- } else {
- // search for it.
- d = mManager.getUserLayoutDevice(deviceName);
- }
-
- if (d != null) {
- // then if there was no config, we add it, otherwise we edit it
- // (same method that adds/replace a config).
- // FIXME this doesn't check if the name was already taken.
- mManager.addUserConfiguration(d, configName, config);
-
- mTreeViewer.refresh();
- select(d, configName);
- }
- }
- }
- });
-
- mEditButton = new Button(buttons, SWT.PUSH | SWT.FLAT);
- mEditButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
- mEditButton.setText("Edit...");
- mEditButton.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- DeviceSelection selection = getSelection();
- ConfigEditDialog dlg = new ConfigEditDialog(parent.getShell(), null);
- dlg.setDeviceName(selection.device.getName());
- dlg.setXDpi(selection.device.getXDpi());
- dlg.setYDpi(selection.device.getYDpi());
- dlg.setConfigName(selection.config.getName());
- dlg.setConfig(selection.config.getConfig());
-
- if (dlg.open() == Window.OK) {
- String deviceName = dlg.getDeviceName();
- String configName = dlg.getConfigName();
- FolderConfiguration config = new FolderConfiguration();
- dlg.getConfig(config);
-
- // replace the device if needed.
- // FIXME: this doesn't check if the replacement name doesn't exist already.
- LayoutDevice d = mManager.replaceUserDevice(selection.device, deviceName,
- dlg.getXDpi(), dlg.getYDpi());
-
- // and add/replace the config
- mManager.replaceUserConfiguration(d, selection.config.getName(), configName,
- config);
-
- mTreeViewer.refresh();
- select(d, configName);
- }
- }
- });
-
- mCopyButton = new Button(buttons, SWT.PUSH | SWT.FLAT);
- mCopyButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
- mCopyButton.setText("Copy");
- mCopyButton.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- DeviceSelection selection = getSelection();
-
- // is the source a default/add-on device, or are we copying a full device?
- // if so the target device is a new device.
- LayoutDevice targetDevice = selection.device;
- if (selection.type == DeviceType.DEFAULT || selection.type == DeviceType.ADDON ||
- selection.config == null) {
- // create a new device
- targetDevice = mManager.addUserDevice(
- selection.device.getName() + " Copy", // new name
- selection.device.getXDpi(),
- selection.device.getYDpi());
- }
-
- String newConfigName = null; // name of the single new config. used for the select.
-
- // are we copying the full device?
- if (selection.config == null) {
- // get the config from the origin device
- List<DeviceConfig> configs = selection.device.getConfigs();
-
- // and copy them in the target device
- for (DeviceConfig config : configs) {
- // we need to make a copy of the config object, or it could be modified
- // in default/addon by editing the version in the new device.
- FolderConfiguration copy = new FolderConfiguration();
- copy.set(config.getConfig());
-
- // the name can stay the same since we are copying a full device
- // and the target device has its own new name.
- mManager.addUserConfiguration(targetDevice, config.getName(), copy);
- }
- } else {
- // only copy the config. target device is not the same as the selection, don't
- // change the config name as we already changed the name of the device.
- newConfigName = (selection.device != targetDevice) ?
- selection.config.getName() : selection.config.getName() + " Copy";
-
- // copy of the config
- FolderConfiguration copy = new FolderConfiguration();
- copy.set(selection.config.getConfig());
-
- // and create the config
- mManager.addUserConfiguration(targetDevice, newConfigName, copy);
- }
-
- mTreeViewer.refresh();
-
- select(targetDevice, newConfigName);
- }
- });
-
- mDeleteButton = new Button(buttons, SWT.PUSH | SWT.FLAT);
- mDeleteButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
- mDeleteButton.setText("Delete");
- mDeleteButton.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- DeviceSelection selection = getSelection();
-
- if (selection.config != null) {
- mManager.removeUserConfiguration(selection.device, selection.config.getName());
- } else if (selection.device != null) {
- mManager.removeUserDevice(selection.device);
- }
-
- mTreeViewer.refresh();
-
- // either select the device (if we removed a entry, or the top custom node if
- // we removed a device)
- select(selection.config != null ? selection.device : null, null);
- }
- });
-
- Label separator = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL);
- separator.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
- gd.horizontalSpan = 2;
-
- mTreeViewer.setInput(mManager);
- setEnabled(null); // no selection at the start
- }
-
- @Override
- protected void createButtonsForButtonBar(Composite parent) {
- // we only want an OK button.
- createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
- }
-
- /**
- * Returns a {@link DeviceSelection} object representing the selected path in the
- * {@link TreeViewer}
- */
- private DeviceSelection getSelection() {
- // get the selection paths
- TreeSelection selection = (TreeSelection)mTreeViewer.getSelection();
- TreePath[] paths =selection.getPaths();
-
- if (paths.length == 0) {
- return null;
- }
-
- TreePath pathSelection = paths[0];
-
- DeviceType type = (DeviceType)pathSelection.getFirstSegment();
- LayoutDevice device = null;
- DeviceConfig config = null;
- switch (pathSelection.getSegmentCount()) {
- case 2: // layout device is selected
- device = (LayoutDevice)pathSelection.getLastSegment();
- break;
- case 3: // config is selected
- device = (LayoutDevice)pathSelection.getSegment(1);
- config = (DeviceConfig)pathSelection.getLastSegment();
- }
-
- return new DeviceSelection(type, device, config);
- }
-
- /**
- * Enables/disables the action button based on the {@link DeviceSelection}.
- * @param selection the selection
- */
- protected void setEnabled(DeviceSelection selection) {
- if (selection == null) {
- mNewButton.setEnabled(false);
- mEditButton.setEnabled(false);
- mCopyButton.setEnabled(false);
- mDeleteButton.setEnabled(false);
- } else {
- switch (selection.type) {
- case DEFAULT:
- case ADDON:
- // only allow copy if device is not null
- mNewButton.setEnabled(false);
- mEditButton.setEnabled(false);
- mDeleteButton.setEnabled(false);
- mCopyButton.setEnabled(selection.device != null);
- break;
- case CUSTOM:
- mNewButton.setEnabled(true); // always true to create new devices.
- mEditButton.setEnabled(selection.config != null); // only edit config for now
-
- boolean enabled = selection.device != null; // need at least selected device
- mDeleteButton.setEnabled(enabled); // for delete and copy buttons
- mCopyButton.setEnabled(enabled);
- break;
- }
- }
- }
-
- /**
- * Selects a device and optionally a config. Because this is meant to show newly created/edited
- * device/config, it'll only do so for {@link DeviceType#CUSTOM} devices.
- * @param device the device to select
- * @param configName the config to select (optional)
- */
- private void select(LayoutDevice device, String configName) {
- Object[] path;
- if (device == null) {
- // select the "custom" node
- path = new Object[] { DeviceType.CUSTOM };
- } else if (configName == null) {
- // this is the easy case. no config to select
- path = new Object[] { DeviceType.CUSTOM, device };
- } else {
- // this is more complex. we have the configName, but the tree contains DeviceConfig
- // Look for the entry.
- DeviceConfig match = null;
- for (DeviceConfig config : device.getConfigs()) {
- if (config.getName().equals(configName)) {
- match = config;
- break;
- }
- }
-
- if (match != null) {
- path = new Object[] { DeviceType.CUSTOM, device, match };
- } else {
- path = new Object[] { DeviceType.CUSTOM, device };
- }
- }
-
- mTreeViewer.setSelection(new TreeSelection(new TreePath(path)), true /*reveal*/);
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigurationComposite.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigurationComposite.java
index 2e1434f..b4e052f 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigurationComposite.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigurationComposite.java
@@ -33,6 +33,7 @@ import com.android.ide.common.resources.ResourceFile;
import com.android.ide.common.resources.ResourceFolder;
import com.android.ide.common.resources.ResourceRepository;
import com.android.ide.common.resources.configuration.DensityQualifier;
+import com.android.ide.common.resources.configuration.DeviceConfigHelper;
import com.android.ide.common.resources.configuration.FolderConfiguration;
import com.android.ide.common.resources.configuration.LanguageQualifier;
import com.android.ide.common.resources.configuration.NightModeQualifier;
@@ -53,9 +54,6 @@ import com.android.ide.eclipse.adt.internal.resources.ResourceHelper;
import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResources;
import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager;
import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
-import com.android.ide.eclipse.adt.internal.sdk.LayoutDevice;
-import com.android.ide.eclipse.adt.internal.sdk.LayoutDevice.DeviceConfig;
-import com.android.ide.eclipse.adt.internal.sdk.LayoutDeviceManager;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.resources.Density;
import com.android.resources.NightMode;
@@ -66,6 +64,10 @@ import com.android.resources.ScreenSize;
import com.android.resources.UiMode;
import com.android.sdklib.AndroidVersion;
import com.android.sdklib.IAndroidTarget;
+import com.android.sdklib.devices.Device;
+import com.android.sdklib.devices.State;
+import com.android.sdklib.internal.avd.AvdInfo;
+import com.android.sdklib.internal.avd.AvdManager;
import com.android.sdklib.repository.PkgProps;
import com.android.sdklib.util.SparseIntArray;
import com.android.util.Pair;
@@ -118,6 +120,7 @@ import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
+import java.util.TreeMap;
/**
* A composite that displays the current configuration displayed in a Graphical Layout Editor.
@@ -189,7 +192,7 @@ public class ConfigurationComposite extends Composite implements SelectionListen
/** updates are disabled if > 0 */
private int mDisableUpdates = 0;
- private List<LayoutDevice> mDeviceList;
+ private List<Device> mDeviceList = new ArrayList<Device>();
private final List<IAndroidTarget> mTargetList = new ArrayList<IAndroidTarget>();
private final List<String> mThemeList = new ArrayList<String>();
@@ -284,8 +287,8 @@ public class ConfigurationComposite extends Composite implements SelectionListen
* rendering to its original configuration.
*/
private class ConfigState {
- LayoutDevice device;
- String configName;
+ Device device;
+ String stateName;
ResourceQualifier[] locale;
String theme;
// TODO: Need to know if it's the project theme or the framework theme!
@@ -302,14 +305,14 @@ public class ConfigurationComposite extends Composite implements SelectionListen
if (device != null) {
sb.append(device.getName());
sb.append(SEP);
- if (configName == null) {
- DeviceConfig config = getSelectedDeviceConfig();
- if (config != null) {
- configName = config.getName();
+ if (stateName == null) {
+ State state= getSelectedDeviceState();
+ if (state != null) {
+ stateName = state.getName();
}
}
- if (configName != null) {
- sb.append(configName);
+ if (stateName != null) {
+ sb.append(stateName);
}
sb.append(SEP);
if (isLocaleSpecificLayout() && locale != null) {
@@ -357,17 +360,17 @@ public class ConfigurationComposite extends Composite implements SelectionListen
boolean setData(String data) {
String[] values = data.split(SEP);
if (values.length >= 6 && values.length <= 8) {
- for (LayoutDevice d : mDeviceList) {
+ for (Device d : mDeviceList) {
if (d.getName().equals(values[0])) {
device = d;
FolderConfiguration config = null;
if (!values[1].isEmpty() && !values[1].equals("null")) { //$NON-NLS-1$
- configName = values[1];
- config = device.getFolderConfigByName(configName);
- } else if (device.getConfigs().size() > 0) {
- DeviceConfig first = device.getConfigs().get(0);
- configName = first.getName();
- config = first.getConfig();
+ stateName = values[1];
+ config = DeviceConfigHelper.getFolderConfig(device, stateName);
+ } else if (device.getAllStates().size() > 0) {
+ State first = device.getAllStates().get(0);
+ stateName = first.getName();
+ config = DeviceConfigHelper.getFolderConfig(first);
}
if (config != null) {
// Load locale. Note that this can get overwritten by the
@@ -507,7 +510,7 @@ public class ConfigurationComposite extends Composite implements SelectionListen
mOrientationCombo = new ToolItem(toolBar, SWT.DROP_DOWN);
mOrientationCombo.setImage(icons.getIcon(ICON_PORTRAIT));
- mOrientationCombo.setToolTipText("Flip Orientation");
+ mOrientationCombo.setToolTipText("Go to next state");
@SuppressWarnings("unused")
ToolItem separator4 = new ToolItem(toolBar, SWT.SEPARATOR);
@@ -752,7 +755,7 @@ public class ConfigurationComposite extends Composite implements SelectionListen
if (loadedConfigData) {
// first make sure we have the config to adapt
selectDevice(mState.device);
- selectConfig(mState.configName);
+ selectState(mState.stateName);
adaptConfigSelection(false /*needBestMatch*/);
@@ -1145,12 +1148,12 @@ public class ConfigurationComposite extends Composite implements SelectionListen
private static class ConfigMatch {
final FolderConfiguration testConfig;
- final LayoutDevice device;
+ final Device device;
final String name;
final ConfigBundle bundle;
- public ConfigMatch(FolderConfiguration testConfig,
- LayoutDevice device, String name, ConfigBundle bundle) {
+ public ConfigMatch(FolderConfiguration testConfig, Device device, String name,
+ ConfigBundle bundle) {
this.testConfig = testConfig;
this.device = device;
this.name = name;
@@ -1171,10 +1174,11 @@ public class ConfigurationComposite extends Composite implements SelectionListen
* the current config. This must only be true if the current config is compatible.
*/
private void findAndSetCompatibleConfig(boolean favorCurrentConfig) {
- // list of compatible device/config/locale
+ // list of compatible device/state/locale
List<ConfigMatch> anyMatches = new ArrayList<ConfigMatch>();
- // list of actual best match (ie the file is a best match for the device/config)
+ // list of actual best match (ie the file is a best match for the
+ // device/state)
List<ConfigMatch> bestMatches = new ArrayList<ConfigMatch>();
// get a locale that match the host locale roughly (may not be exact match on the region.)
@@ -1219,27 +1223,30 @@ public class ConfigurationComposite extends Composite implements SelectionListen
addRenderTargetToBundles(configBundles);
- for (LayoutDevice device : mDeviceList) {
- for (DeviceConfig config : device.getConfigs()) {
+ for (Device device : mDeviceList) {
+ for (State state : device.getAllStates()) {
- // loop on the list of config bundles to create full configurations.
+ // loop on the list of config bundles to create full
+ // configurations.
+ FolderConfiguration stateConfig = DeviceConfigHelper.getFolderConfig(state);
for (ConfigBundle bundle : configBundles) {
// create a new config with device config
FolderConfiguration testConfig = new FolderConfiguration();
- testConfig.set(config.getConfig());
+ testConfig.set(stateConfig);
// add on top of it, the extra qualifiers from the bundle
testConfig.add(bundle.config);
if (mEditedConfig.isMatchFor(testConfig)) {
- // this is a basic match. record it in case we don't find a match
+ // this is a basic match. record it in case we don't
+ // find a match
// where the edited file is a best config.
- anyMatches.add(new ConfigMatch(testConfig, device, config.getName(),
- bundle));
+ anyMatches
+ .add(new ConfigMatch(testConfig, device, state.getName(), bundle));
if (isCurrentFileBestMatchFor(testConfig)) {
// this is what we want.
- bestMatches.add(new ConfigMatch(testConfig, device, config.getName(),
+ bestMatches.add(new ConfigMatch(testConfig, device, state.getName(),
bundle));
}
}
@@ -1267,7 +1274,7 @@ public class ConfigurationComposite extends Composite implements SelectionListen
// select the best device anyway.
ConfigMatch match = selectConfigMatch(anyMatches);
selectDevice(mState.device = match.device);
- selectConfig(match.name);
+ selectState(match.name);
selectLocale(mLocaleList.get(match.bundle.localeIndex));
mState.uiMode = UiMode.getByIndex(match.bundle.dockModeIndex);
@@ -1285,13 +1292,13 @@ public class ConfigurationComposite extends Composite implements SelectionListen
} else {
// TODO: there is no device/config able to display the layout, create one.
- // For the base config values, we'll take the first device and config,
+ // For the base config values, we'll take the first device and state,
// and replace whatever qualifier required by the layout file.
}
} else {
ConfigMatch match = selectConfigMatch(bestMatches);
selectDevice(mState.device = match.device);
- selectConfig(match.name);
+ selectState(match.name);
selectLocale(mLocaleList.get(match.bundle.localeIndex));
mState.uiMode = UiMode.getByIndex(match.bundle.dockModeIndex);
mState.night = NightMode.getByIndex(match.bundle.nightModeIndex);
@@ -1493,10 +1500,9 @@ public class ConfigurationComposite extends Composite implements SelectionListen
// check the device config (ie sans locale)
boolean needConfigChange = true; // if still true, we need to find another config.
boolean currentConfigIsCompatible = false;
- DeviceConfig selectedConfig = getSelectedDeviceConfig();
- if (selectedConfig != null) {
- String configName = selectedConfig.getName();
- FolderConfiguration currentConfig = mState.device.getFolderConfigByName(configName);
+ State selectedState = getSelectedDeviceState();
+ if (selectedState != null) {
+ FolderConfiguration currentConfig = DeviceConfigHelper.getFolderConfig(selectedState);
if (currentConfig != null && mEditedConfig.isMatchFor(currentConfig)) {
currentConfigIsCompatible = true; // current config is compatible
if (needBestMatch == false || isCurrentFileBestMatchFor(currentConfig)) {
@@ -1506,15 +1512,15 @@ public class ConfigurationComposite extends Composite implements SelectionListen
}
if (needConfigChange) {
- // if the current config/locale isn't a correct match, then
- // look for another config/locale in the same device.
+ // if the current state/locale isn't a correct match, then
+ // look for another state/locale in the same device.
FolderConfiguration testConfig = new FolderConfiguration();
// first look in the current device.
String matchName = null;
int localeIndex = -1;
- mainloop: for (DeviceConfig config : mState.device.getConfigs()) {
- testConfig.set(config.getConfig());
+ mainloop: for (State state : mState.device.getAllStates()) {
+ testConfig.set(DeviceConfigHelper.getFolderConfig(state));
// loop on the locales.
for (int i = 0 ; i < mLocaleList.size() ; i++) {
@@ -1526,7 +1532,7 @@ public class ConfigurationComposite extends Composite implements SelectionListen
if (mEditedConfig.isMatchFor(testConfig) &&
isCurrentFileBestMatchFor(testConfig)) {
- matchName = config.getName();
+ matchName = state.getName();
localeIndex = i;
break mainloop;
}
@@ -1534,11 +1540,12 @@ public class ConfigurationComposite extends Composite implements SelectionListen
}
if (matchName != null) {
- selectConfig(matchName);
+ selectState(matchName);
selectLocale(mLocaleList.get(localeIndex));
} else {
- // no match in current device with any config/locale
- // attempt to find another device that can display this particular config.
+ // no match in current device with any state/locale
+ // attempt to find another device that can display this
+ // particular state.
findAndSetCompatibleConfig(currentConfigIsCompatible);
}
}
@@ -1590,9 +1597,9 @@ public class ConfigurationComposite extends Composite implements SelectionListen
private void saveState() {
if (mDisableUpdates == 0) {
- DeviceConfig deviceConfig = getSelectedDeviceConfig();
- String configName = deviceConfig != null ? deviceConfig.getName() : null;
- mState.configName = configName;
+ State state = getSelectedDeviceState();
+ String stateName = state != null ? state.getName() : null;
+ mState.stateName = stateName;
// since the locales are relative to the project, only keeping the index is enough
mState.locale = getSelectedLocale();
@@ -1721,7 +1728,10 @@ public class ConfigurationComposite extends Composite implements SelectionListen
}
}
- private String getDeviceLabel(LayoutDevice device, boolean brief) {
+ private String getDeviceLabel(Device device, boolean brief) {
+ if(device == null) {
+ return "";
+ }
String name = device.getName();
if (brief) {
@@ -1747,40 +1757,71 @@ public class ConfigurationComposite extends Composite implements SelectionListen
Listener menuListener = new Listener() {
@Override
public void handleEvent(Event event) {
+ Device current = getSelectedDevice();
Menu menu = new Menu(ConfigurationComposite.this.getShell(), SWT.POP_UP);
- LayoutDevice current = getSelectedDevice();
- if (mDeviceList != null && mDeviceList.size() > 0) {
- for (final LayoutDevice device : mDeviceList) {
- String title = getDeviceLabel(device, false);
- MenuItem item = new MenuItem(menu, SWT.CHECK);
- item.setText(title);
+ AvdManager avdManager = Sdk.getCurrent().getAvdManager();
+ AvdInfo[] avds = avdManager.getValidAvds();
+ boolean separatorNeeded = false;
+ for (AvdInfo avd : avds) {
+ for (final Device d : mDeviceList) {
+ if (d.getManufacturer().equals(avd.getDeviceManufacturer())
+ && d.getName().equals(avd.getDeviceName())) {
+ separatorNeeded = true;
+ MenuItem item = new MenuItem(menu, SWT.CHECK);
+ item.setText(avd.getName());
+ item.setSelection(current == d);
- boolean selected = current == device;
- if (selected) {
- item.setSelection(true);
- }
+ item.addSelectionListener(new SelectionAdapter() {
- item.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- selectDevice(device);
- onDeviceChange(true /*recomputeLayout*/);
- }
- });
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ selectDevice(d);
+ onDeviceChange(true /*recomputeLayout*/);
+ }
+ });
+ }
}
+ }
+ if (separatorNeeded) {
@SuppressWarnings("unused")
MenuItem separator = new MenuItem(menu, SWT.SEPARATOR);
+ }
- MenuItem item = new MenuItem(menu, SWT.PUSH);
- item.setText("Add Custom...");
- item.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- onCustomDeviceConfig();
+ // Group the devices by manufacturer, then put them in the menu
+ if (!mDeviceList.isEmpty()) {
+ Map<String, List<Device>> manufacturers = new TreeMap<String, List<Device>>();
+ for (Device device : mDeviceList) {
+ List<Device> devices;
+ if(manufacturers.containsKey(device.getManufacturer())) {
+ devices = manufacturers.get(device.getManufacturer());
+ } else {
+ devices = new ArrayList<Device>();
+ manufacturers.put(device.getManufacturer(), devices);
}
- });
+ devices.add(device);
+ }
+ for (List<Device> devices : manufacturers.values()) {
+ MenuItem item = new MenuItem(menu, SWT.CASCADE);
+ item.setText(devices.get(0).getManufacturer());
+ Menu manufacturerMenu = new Menu(menu);
+ item.setMenu(manufacturerMenu);
+ for (final Device d : devices) {
+ MenuItem deviceItem = new MenuItem(manufacturerMenu, SWT.CHECK);
+ deviceItem.setText(d.getName());
+ deviceItem.setSelection(current == d);
+
+ deviceItem.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ selectDevice(d);
+ onDeviceChange(true /*recomputeLayout*/);
+ }
+ });
+ }
+ }
}
@@ -1849,31 +1890,31 @@ public class ConfigurationComposite extends Composite implements SelectionListen
if (event.detail == SWT.ARROW) {
OrientationMenuAction.showMenu(ConfigurationComposite.this, combo);
} else {
- flipOrientation();
+ gotoNextState();
}
}
};
combo.addListener(SWT.Selection, menuListener);
}
- /** Flip the current orientation to the next available device orientation, if any */
- private void flipOrientation() {
- DeviceConfig config = getSelectedDeviceConfig();
- DeviceConfig flipped = getNextDeviceConfig(getSelectedDeviceConfig());
- if (flipped != config) {
- selectDeviceConfig(flipped);
+ /** Move to the next device state, changing the icon if it changes orientation */
+ private void gotoNextState() {
+ State state = getSelectedDeviceState();
+ State flipped = getNextDeviceState(state);
+ if (flipped != state) {
+ selectDeviceState(flipped);
onDeviceConfigChange();
}
}
- /** Get the next cyclical orientation after the given orientation */
+ /** Get the next cyclical state after the given state */
@Nullable
- DeviceConfig getNextDeviceConfig(DeviceConfig config) {
- LayoutDevice device = getSelectedDevice();
- List<DeviceConfig> configs = device.getConfigs();
- for (int i = 0; i < configs.size(); i++) {
- if (configs.get(i) == config) {
- return configs.get((i + 1) % configs.size());
+ State getNextDeviceState(State state) {
+ Device device = getSelectedDevice();
+ List<State> states = device.getAllStates();
+ for (int i = 0; i < states.size(); i++) {
+ if (states.get(i) == state) {
+ return states.get((i + 1) % states.size());
}
}
@@ -2304,13 +2345,13 @@ public class ConfigurationComposite extends Composite implements SelectionListen
IProject project = mEditedFile.getProject();
ManifestInfo manifest = ManifestInfo.get(project);
- // Look up the screen size for the current configuration
+ // Look up the screen size for the current state
ScreenSize screenSize = null;
if (mState.device != null) {
- List<DeviceConfig> configs = mState.device.getConfigs();
- for (DeviceConfig config : configs) {
+ List<State> states = mState.device.getAllStates();
+ for (State state : states) {
ScreenSizeQualifier qualifier =
- config.getConfig().getScreenSizeQualifier();
+ DeviceConfigHelper.getFolderConfig(state).getScreenSizeQualifier();
screenSize = qualifier.getValue();
break;
}
@@ -2378,7 +2419,12 @@ public class ConfigurationComposite extends Composite implements SelectionListen
*/
public float getXDpi() {
if (mState.device != null) {
- float dpi = mState.device.getXDpi();
+
+ State currState = mState.device.getState(mState.stateName);
+ if (currState == null) {
+ currState = mState.device.getDefaultState();
+ }
+ float dpi = (float) currState.getHardware().getScreen().getXdpi();
if (Float.isNaN(dpi) == false) {
return dpi;
}
@@ -2393,7 +2439,12 @@ public class ConfigurationComposite extends Composite implements SelectionListen
*/
public float getYDpi() {
if (mState.device != null) {
- float dpi = mState.device.getYDpi();
+
+ State currState = mState.device.getState(mState.stateName);
+ if (currState == null) {
+ currState = mState.device.getDefaultState();
+ }
+ float dpi = (float) currState.getHardware().getScreen().getYdpi();
if (Float.isNaN(dpi) == false) {
return dpi;
}
@@ -2459,7 +2510,7 @@ public class ConfigurationComposite extends Composite implements SelectionListen
* @return the device name, or null
*/
public String getDevice() {
- LayoutDevice device = getSelectedDevice();
+ Device device = getSelectedDevice();
if (device != null) {
return device.getName();
}
@@ -2530,24 +2581,22 @@ public class ConfigurationComposite extends Composite implements SelectionListen
}
/**
- * Loads the list of {@link LayoutDevice} and inits the UI with it.
+ * Loads the list of {@link Device}s and inits the UI with it.
*/
private void initDevices() {
- mDeviceList = null;
-
Sdk sdk = Sdk.getCurrent();
if (sdk != null) {
- LayoutDeviceManager manager = sdk.getLayoutDeviceManager();
- mDeviceList = manager.getCombinedList();
+ mDeviceList = sdk.getDevices();
+ } else {
+ mDeviceList = new ArrayList<Device>();
}
-
// fill with the devices
- if (mDeviceList != null && mDeviceList.size() > 0) {
- LayoutDevice first = mDeviceList.get(0);
+ if (!mDeviceList.isEmpty()) {
+ Device first = mDeviceList.get(0);
selectDevice(first);
- List<DeviceConfig> configs = first.getConfigs();
- selectDeviceConfig(configs.get(0));
+ List<State> states = first.getAllStates();
+ selectDeviceState(states.get(0));
} else {
selectDevice(null);
}
@@ -2580,11 +2629,11 @@ public class ConfigurationComposite extends Composite implements SelectionListen
}
@NonNull
- ScreenOrientation getOrientation(DeviceConfig config) {
- ScreenOrientationQualifier qualifier = config.getConfig().getScreenOrientationQualifier();
+ ScreenOrientation getOrientation(State state) {
+ FolderConfiguration config = DeviceConfigHelper.getFolderConfig(state);
ScreenOrientation orientation = null;
- if (qualifier != null) {
- orientation = qualifier.getValue();
+ if (config != null && config.getScreenOrientationQualifier() != null) {
+ orientation = config.getScreenOrientationQualifier().getValue();
}
if (orientation == null) {
@@ -2594,24 +2643,24 @@ public class ConfigurationComposite extends Composite implements SelectionListen
return orientation;
}
- void selectDeviceConfig(@Nullable DeviceConfig config) {
- mOrientationCombo.setData(config);
+ void selectDeviceState(@Nullable State state) {
+ mOrientationCombo.setData(state);
- DeviceConfig nextConfig = getNextDeviceConfig(config);
- mOrientationCombo.setImage(getOrientationIcon(getOrientation(nextConfig),
- nextConfig != config));
+ State nextState = getNextDeviceState(state);
+ mOrientationCombo.setImage(getOrientationIcon(getOrientation(state),
+ nextState != state));
}
- DeviceConfig getSelectedDeviceConfig() {
- return (DeviceConfig) mOrientationCombo.getData();
+ State getSelectedDeviceState() {
+ return (State) mOrientationCombo.getData();
}
/**
- * Selects a given {@link LayoutDevice} in the device combo, if it is found.
+ * Selects a given {@link Device} in the device combo, if it is found.
* @param device the device to select
* @return true if the device was found.
*/
- private boolean selectDevice(@Nullable LayoutDevice device) {
+ private boolean selectDevice(@Nullable Device device) {
mDeviceCombo.setData(device);
if (device != null) {
mDeviceCombo.setText(getDeviceLabel(device, true));
@@ -2623,21 +2672,22 @@ public class ConfigurationComposite extends Composite implements SelectionListen
return false;
}
- LayoutDevice getSelectedDevice() {
- return (LayoutDevice) mDeviceCombo.getData();
+ @Nullable
+ Device getSelectedDevice() {
+ return (Device) mDeviceCombo.getData();
}
/**
- * Selects a config by name.
- * @param name the name of the config to select.
+ * Selects a state by name.
+ * @param name the name of the state to select.
*/
- private void selectConfig(String name) {
- LayoutDevice device = getSelectedDevice();
- DeviceConfig config = null;
+ private void selectState(String name) {
+ Device device = getSelectedDevice();
+ State state = null;
if (device != null) {
- config = device.getDeviceConfigByName(name);
+ state = device.getState(name);
}
- selectDeviceConfig(config);
+ selectDeviceState(state);
}
/**
@@ -2653,17 +2703,16 @@ public class ConfigurationComposite extends Composite implements SelectionListen
String newConfigName = null;
- DeviceConfig prevConfig = getSelectedDeviceConfig();
- LayoutDevice device = getSelectedDevice();
- if (mState.device != null && prevConfig != null && device != null) {
+ State prevState = getSelectedDeviceState();
+ Device device = getSelectedDevice();
+ if (mState.device != null && prevState != null && device != null) {
// get the previous config, so that we can look for a close match
- FolderConfiguration oldConfig = mState.device.getFolderConfigByName(
- prevConfig.getName());
- newConfigName = getClosestMatch(oldConfig, device.getConfigs());
+ FolderConfiguration oldConfig = DeviceConfigHelper.getFolderConfig(prevState);
+ newConfigName = getClosestMatch(oldConfig, device.getAllStates());
}
mState.device = device;
- selectConfig(newConfigName);
+ selectState(newConfigName);
computeCurrentConfig();
@@ -2673,80 +2722,37 @@ public class ConfigurationComposite extends Composite implements SelectionListen
}
/**
- * Handles a user request for the {@link ConfigManagerDialog}.
- */
- private void onCustomDeviceConfig() {
- ConfigManagerDialog dialog = new ConfigManagerDialog(getShell());
- dialog.open();
-
- // save the user devices
- Sdk.getCurrent().getLayoutDeviceManager().save();
-
- // Update the UI with no triggered event
- mDisableUpdates++;
-
- try {
- LayoutDevice oldCurrent = mState.device;
-
- // but first, update the device combo
- initDevices();
-
- // attempts to reselect the current device.
- if (selectDevice(oldCurrent)) {
- // current device still exists.
- // reselect the config
- selectConfig(mState.configName);
-
- // reset the UI as if it was just a replacement file, since we can keep
- // the current device (and possibly config).
- adaptConfigSelection(false /*needBestMatch*/);
-
- } else {
- // find a new device/config to match the current file.
- findAndSetCompatibleConfig(false /*favorCurrentConfig*/);
- }
- } finally {
- mDisableUpdates--;
- }
-
- // recompute the current config
- computeCurrentConfig();
-
- // force a redraw
- onDeviceChange(true /*recomputeLayout*/);
- }
-
- /**
- * Attempts to find a close config among a list
+ * Attempts to find a close state among a list
* @param oldConfig the reference config.
- * @param configs the list of config to search through
- * @return the name of the closest config match, or possibly null if no configs are compatible
- * (this can only happen if the configs don't have a single qualifier that is the same).
+ * @param states the list of states to search through
+ * @return the name of the closest state match, or possibly null if no states are compatible
+ * (this can only happen if the states don't have a single qualifier that is the same).
*/
- private String getClosestMatch(FolderConfiguration oldConfig, List<DeviceConfig> configs) {
+ private String getClosestMatch(FolderConfiguration oldConfig, List<State> states) {
- // create 2 lists as we're going to go through one and put the candidates in the other.
- ArrayList<DeviceConfig> list1 = new ArrayList<DeviceConfig>();
- ArrayList<DeviceConfig> list2 = new ArrayList<DeviceConfig>();
+ // create 2 lists as we're going to go through one and put the
+ // candidates in the other.
+ ArrayList<State> list1 = new ArrayList<State>();
+ ArrayList<State> list2 = new ArrayList<State>();
- list1.addAll(configs);
+ list1.addAll(states);
final int count = FolderConfiguration.getQualifierCount();
for (int i = 0 ; i < count ; i++) {
- // compute the new candidate list by only taking configs that have
- // the same i-th qualifier as the old config
- for (DeviceConfig c : list1) {
+ // compute the new candidate list by only taking states that have
+ // the same i-th qualifier as the old state
+ for (State s : list1) {
ResourceQualifier oldQualifier = oldConfig.getQualifier(i);
- FolderConfiguration folderConfig = c.getConfig();
+ FolderConfiguration folderConfig = DeviceConfigHelper.getFolderConfig(s);
ResourceQualifier newQualifier = folderConfig.getQualifier(i);
if (oldQualifier == null) {
if (newQualifier == null) {
- list2.add(c);
+ list2.add(s);
}
} else if (oldQualifier.equals(newQualifier)) {
- list2.add(c);
+ list2.add(s);
}
}
@@ -2756,9 +2762,9 @@ public class ConfigurationComposite extends Composite implements SelectionListen
return list2.get(0).getName();
}
- // if the list is empty, then all the new configs failed. It is considered ok, and
+ // if the list is empty, then all the new states failed. It is considered ok, and
// we move to the next qualifier anyway. This way, if a qualifier is different for
- // all new configs it is simply ignored.
+ // all new states it is simply ignored.
if (list2.size() != 0) {
// move the candidates back into list1.
list1.clear();
@@ -2768,7 +2774,7 @@ public class ConfigurationComposite extends Composite implements SelectionListen
}
// the only way to reach this point is if there's an exact match.
- // (if there are more than one, then there's a duplicate config and it doesn't matter,
+ // (if there are more than one, then there's a duplicate state and it doesn't matter,
// we take the first one).
if (list1.size() > 0) {
return list1.get(0).getName();
@@ -2861,9 +2867,9 @@ public class ConfigurationComposite extends Composite implements SelectionListen
saveState();
if (mState.device != null) {
- // get the device config from the device/config combos.
- FolderConfiguration config = mState.device.getFolderConfigByName(
- getSelectedDeviceConfig().getName());
+ // get the device config from the device/state combos.
+ FolderConfiguration config =
+ DeviceConfigHelper.getFolderConfig(getSelectedDeviceState());
// replace the config with the one from the device
mCurrentConfig.set(config);
@@ -2877,6 +2883,18 @@ public class ConfigurationComposite extends Composite implements SelectionListen
(RegionQualifier)localeQualifiers[LOCALE_REGION]);
}
+ // Replace the UiMode with the selected one, if one is selected
+ UiMode uiMode = getSelectedUiMode();
+ if (uiMode != null) {
+ mCurrentConfig.setUiModeQualifier(new UiModeQualifier(uiMode));
+ }
+
+ // Replace the NightMode with the selected one, if one is selected
+ NightMode night = getSelectedNightMode();
+ if (night != null) {
+ mCurrentConfig.setNightModeQualifier(new NightModeQualifier(night));
+ }
+
// replace the API level by the selection of the combo
IAndroidTarget target = getRenderingTarget();
if (target == null) {
@@ -3209,7 +3227,7 @@ public class ConfigurationComposite extends Composite implements SelectionListen
final Object source = e.getSource();
if (source == mOrientationCombo) {
- flipOrientation();
+ gotoNextState();
}
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/OrientationMenuAction.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/OrientationMenuAction.java
index c2f32c5..27446b2 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/OrientationMenuAction.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/OrientationMenuAction.java
@@ -22,6 +22,10 @@ import com.android.ide.eclipse.adt.internal.sdk.LayoutDevice.DeviceConfig;
import com.android.resources.NightMode;
import com.android.resources.ScreenOrientation;
import com.android.resources.UiMode;
+import com.android.sdklib.devices.Device;
+import com.android.sdklib.devices.DeviceManager;
+import com.android.sdklib.devices.State;
+
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ActionContributionItem;
@@ -59,19 +63,19 @@ class OrientationMenuAction extends SubmenuAction {
MenuManager manager = new MenuManager();
// Show toggles for all the available configurations
- DeviceConfig current = configuration.getSelectedDeviceConfig();
- LayoutDevice device = configuration.getSelectedDevice();
+ State current = configuration.getSelectedDeviceState();
+ Device device = configuration.getSelectedDevice();
if (device != null) {
- List<DeviceConfig> configs = device.getConfigs();
+ List<State> states = device.getAllStates();
- if (configs.size() > 1 && current != null) {
- DeviceConfig flip = configuration.getNextDeviceConfig(current);
+ if (states.size() > 1 && current != null) {
+ State flip = configuration.getNextDeviceState(current);
manager.add(new DeviceConfigAction(configuration,
String.format("Switch to %1$s", flip.getName()), flip, false, true));
manager.add(new Separator());
}
- for (DeviceConfig config : configs) {
+ for (State config : states) {
manager.add(new DeviceConfigAction(configuration, config.getName(),
config, config == current, false));
}
@@ -150,23 +154,23 @@ class OrientationMenuAction extends SubmenuAction {
private static class DeviceConfigAction extends Action {
private final ConfigurationComposite mConfiguration;
- private final DeviceConfig mConfig;
+ private final State mState;
private DeviceConfigAction(ConfigurationComposite configuration, String title,
- DeviceConfig config, boolean checked, boolean flip) {
+ State state, boolean checked, boolean flip) {
super(title, IAction.AS_RADIO_BUTTON);
mConfiguration = configuration;
- mConfig = config;
+ mState = state;
if (checked) {
setChecked(true);
}
- ScreenOrientation orientation = configuration.getOrientation(config);
+ ScreenOrientation orientation = configuration.getOrientation(state);
setImageDescriptor(configuration.getOrientationImage(orientation, flip));
}
@Override
public void run() {
- mConfiguration.selectDeviceConfig(mConfig);
+ mConfiguration.selectDeviceState(mState);
mConfiguration.onDeviceConfigChange();
}
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java
index 3fed2e0..79c9d62 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java
@@ -44,6 +44,8 @@ import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.ISdkLog;
import com.android.sdklib.SdkConstants;
import com.android.sdklib.SdkManager;
+import com.android.sdklib.devices.Device;
+import com.android.sdklib.devices.DeviceManager;
import com.android.sdklib.internal.avd.AvdManager;
import com.android.sdklib.internal.project.ProjectProperties;
import com.android.sdklib.internal.project.ProjectProperties.PropertyType;
@@ -129,6 +131,7 @@ public final class Sdk {
private final SdkManager mManager;
private final DexWrapper mDexWrapper;
private final AvdManager mAvdManager;
+ private final DeviceManager mDeviceManager;
/** Map associating an {@link IAndroidTarget} to an {@link AndroidTargetData} */
private final HashMap<IAndroidTarget, AndroidTargetData> mTargetDataMap =
@@ -145,8 +148,6 @@ public final class Sdk {
private final String mDocBaseUrl;
- private final LayoutDeviceManager mLayoutDeviceManager = new LayoutDeviceManager();
-
/**
* Classes implementing this interface will receive notification when targets are changed.
*/
@@ -662,8 +663,13 @@ public final class Sdk {
}
}
- public LayoutDeviceManager getLayoutDeviceManager() {
- return mLayoutDeviceManager;
+ public DeviceManager getDeviceManager() {
+ return mDeviceManager;
+ }
+
+ /** Returns the devices provided by the SDK, including user created devices */
+ public List<Device> getDevices() {
+ return mDeviceManager.getDevices(getSdkLocation());
}
/**
@@ -744,10 +750,7 @@ public final class Sdk {
mDocBaseUrl = getDocumentationBaseUrl(mManager.getLocation() +
SdkConstants.OS_SDK_DOCS_FOLDER);
- // load the built-in and user layout devices
- mLayoutDeviceManager.loadDefaultAndUserDevices(mManager.getLocation());
- // and the ones from the add-on
- loadLayoutDevices();
+ mDeviceManager = new DeviceManager(AdtPlugin.getDefault());
// update whatever ProjectState is already present with new IAndroidTarget objects.
synchronized (LOCK) {
@@ -826,24 +829,6 @@ public final class Sdk {
}
/**
- * Parses the SDK add-ons to look for files called {@link SdkConstants#FN_DEVICES_XML} to
- * load {@link LayoutDevice} from them.
- */
- private void loadLayoutDevices() {
- IAndroidTarget[] targets = mManager.getTargets();
- for (IAndroidTarget target : targets) {
- if (target.isPlatform() == false) {
- File deviceXml = new File(target.getLocation(), SdkConstants.FN_DEVICES_XML);
- if (deviceXml.isFile()) {
- mLayoutDeviceManager.parseAddOnLayoutDevice(deviceXml);
- }
- }
- }
-
- mLayoutDeviceManager.sealAddonLayoutDevices();
- }
-
- /**
* Delegate listener for project changes.
*/
private IProjectListener mProjectListener = new IProjectListener() {
diff --git a/eclipse/plugins/com.android.ide.eclipse.base/.classpath b/eclipse/plugins/com.android.ide.eclipse.base/.classpath
index 9b4ea2f..5f09fc7 100644
--- a/eclipse/plugins/com.android.ide.eclipse.base/.classpath
+++ b/eclipse/plugins/com.android.ide.eclipse.base/.classpath
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
+ <classpathentry exported="true" kind="lib" path="libs/dvlib.jar"/>
<classpathentry exported="true" kind="lib" path="libs/androidprefs.jar"/>
<classpathentry exported="true" kind="lib" path="libs/common.jar"/>
<classpathentry exported="true" kind="lib" path="libs/commons-codec-1.4.jar"/>
diff --git a/eclipse/plugins/com.android.ide.eclipse.base/META-INF/MANIFEST.MF b/eclipse/plugins/com.android.ide.eclipse.base/META-INF/MANIFEST.MF
index b03048a..b16d89d 100644
--- a/eclipse/plugins/com.android.ide.eclipse.base/META-INF/MANIFEST.MF
+++ b/eclipse/plugins/com.android.ide.eclipse.base/META-INF/MANIFEST.MF
@@ -19,15 +19,18 @@ Bundle-ClassPath: .,
libs/httpcore-4.1.jar,
libs/httpmime-4.1.1.jar,
libs/sdklib.jar,
- libs/sdkstats.jar
+ libs/sdkstats.jar,
+ libs/dvlib.jar
Export-Package: com.android,
com.android.annotations,
+ com.android.dvlib,
com.android.ide.eclipse.base,
com.android.io,
com.android.prefs,
com.android.resources,
com.android.sdklib,
com.android.sdklib.build,
+ com.android.sdklib.devices,
com.android.sdklib.internal.avd,
com.android.sdklib.internal.build,
com.android.sdklib.internal.project,
diff --git a/eclipse/plugins/com.android.ide.eclipse.base/build.properties b/eclipse/plugins/com.android.ide.eclipse.base/build.properties
index 6dcdd76..15e907d 100644
--- a/eclipse/plugins/com.android.ide.eclipse.base/build.properties
+++ b/eclipse/plugins/com.android.ide.eclipse.base/build.properties
@@ -12,6 +12,7 @@ bin.includes = .,\
libs/httpcore-4.1.jar,\
libs/httpmime-4.1.1.jar,\
libs/sdklib.jar,\
- libs/sdkstats.jar
+ libs/sdkstats.jar,\
+ libs/dvlib.jar
jars.compile.order = .
source.. = src/
diff --git a/eclipse/scripts/create_all_symlinks.sh b/eclipse/scripts/create_all_symlinks.sh
index dbc2cb8..6cf1fb2 100755
--- a/eclipse/scripts/create_all_symlinks.sh
+++ b/eclipse/scripts/create_all_symlinks.sh
@@ -108,7 +108,7 @@ CP_FILES=""
### BASE ###
BASE_PLUGIN_DEST="sdk/eclipse/plugins/com.android.ide.eclipse.base/libs"
-BASE_PLUGIN_LIBS="common sdkstats androidprefs sdklib"
+BASE_PLUGIN_LIBS="common sdkstats androidprefs sdklib dvlib"
BASE_PLUGIN_PREBUILTS="\
prebuilts/tools/common/commons-compress/commons-compress-1.0.jar \
prebuilts/tools/common/guava-tools/guava-10.0.1.jar \
diff --git a/ide_common/src/com/android/ide/common/resources/configuration/DeviceConfigHelper.java b/ide_common/src/com/android/ide/common/resources/configuration/DeviceConfigHelper.java
index 7ed955f..27eaa01 100644
--- a/ide_common/src/com/android/ide/common/resources/configuration/DeviceConfigHelper.java
+++ b/ide_common/src/com/android/ide/common/resources/configuration/DeviceConfigHelper.java
@@ -17,6 +17,8 @@
package com.android.ide.common.resources.configuration;
import com.android.annotations.Nullable;
+import com.android.resources.NightMode;
+import com.android.resources.UiMode;
import com.android.sdklib.devices.Device;
import com.android.sdklib.devices.Hardware;
import com.android.sdklib.devices.Screen;
@@ -64,6 +66,15 @@ public class DeviceConfigHelper {
config.updateScreenWidthAndHeight();
+ // Setup some default qualifiers
+ config.setUiModeQualifier(new UiModeQualifier(UiMode.NORMAL));
+ config.setNightModeQualifier(new NightModeQualifier(NightMode.NOTNIGHT));
+ config.setCountryCodeQualifier(new CountryCodeQualifier());
+ config.setLanguageQualifier(new LanguageQualifier());
+ config.setNetworkCodeQualifier(new NetworkCodeQualifier());
+ config.setRegionQualifier(new RegionQualifier());
+ config.setVersionQualifier(new VersionQualifier());
+
return config;
}
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/DeviceWriter.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/DeviceWriter.java
index 3ecc55e..453a4e5 100644
--- a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/DeviceWriter.java
+++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/DeviceWriter.java
@@ -90,6 +90,7 @@ public class DeviceWriter {
Transformer tf = TransformerFactory.newInstance().newTransformer();
tf.setOutputProperty(OutputKeys.INDENT, "yes");
+ tf.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(out);
tf.transform(source, result);
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/AvdInfo.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/AvdInfo.java
index 463037e..54e2fa7 100755
--- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/AvdInfo.java
+++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/AvdInfo.java
@@ -140,6 +140,24 @@ public final class AvdInfo implements Comparable<AvdInfo> {
return SdkConstants.CPU_ARCH_ARM;
}
+ public String getDeviceManufacturer() {
+ String deviceManufacturer = mProperties.get(AvdManager.AVD_INI_DEVICE_MANUFACTURER);
+ if (deviceManufacturer != null && !deviceManufacturer.isEmpty()) {
+ return deviceManufacturer;
+ }
+
+ return "";
+ }
+
+ public String getDeviceName() {
+ String deviceName = mProperties.get(AvdManager.AVD_INI_DEVICE_NAME);
+ if (deviceName != null && !deviceName.isEmpty()) {
+ return deviceName;
+ }
+
+ return "";
+ }
+
/** Convenience function to return a more user friendly name of the abi type. */
public static String getPrettyAbiType(String raw) {
String s = null;
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/AvdManager.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/AvdManager.java
index 768a835..16bbb38 100644
--- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/AvdManager.java
+++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/AvdManager.java
@@ -86,6 +86,15 @@ public class AvdManager {
*/
public final static String AVD_INI_CPU_MODEL = "hw.cpu.model"; //$NON-NLS-1$
+ /**
+ * AVD/config.ini key name representing the manufacturer of the device this avd was based on.
+ */
+ public static final String AVD_INI_DEVICE_MANUFACTURER = "hw.device.manufacturer"; //$NON-NLS-1$
+
+ /**
+ * AVD/config.ini key name representing the name of the device this avd was based on.
+ */
+ public static final String AVD_INI_DEVICE_NAME = "hw.device.name"; //$NON-NLS-1$
/**
* AVD/config.ini key name representing the SDK-relative path of the skin folder, if any,
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdCreationDialog.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdCreationDialog.java
index 23835e1..0cf52cf 100644
--- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdCreationDialog.java
+++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdCreationDialog.java
@@ -573,6 +573,7 @@ final class AvdCreationDialog extends GridDialog {
mStatusLabel.setText(" \n "); //$NON-NLS-1$
reloadTargetCombo();
+ reloadDeviceCombo();
}
/**
@@ -763,9 +764,25 @@ final class AvdCreationDialog extends GridDialog {
mAvdName.setText(mEditAvdInfo.getName());
+ Map<String, String> props = mEditAvdInfo.getProperties();
+
+ if (props != null) {
+ // Try to match it to a device
+
+ // The device has to be set before everything else because
+ // selecting a device will modify other options
+ for (int i = 0; i < mDeviceList.size(); i++){
+ Device d = mDeviceList.get(i);
+ if(d.getManufacturer().equals(props.get(AvdManager.AVD_INI_DEVICE_MANUFACTURER))
+ && d.getName().equals(props.get(AvdManager.AVD_INI_DEVICE_NAME))) {
+ mDeviceCombo.select(i);
+ break;
+ }
+ }
+ }
+
IAndroidTarget target = mEditAvdInfo.getTarget();
if (target != null && !mCurrentTargets.isEmpty()) {
- mDeviceCombo.setEnabled(true);
// Try to select the target in the target combo.
// This will fail if the AVD needs to be repaired.
//
@@ -776,6 +793,7 @@ final class AvdCreationDialog extends GridDialog {
if (target.equals(mCurrentTargets.get(mTargetCombo.getItem(i)))) {
mTargetCombo.select(i);
reloadAbiTypeCombo();
+ reloadDeviceCombo();
reloadSkinCombo();
break;
}
@@ -797,8 +815,8 @@ final class AvdCreationDialog extends GridDialog {
}
}
- Map<String, String> props = mEditAvdInfo.getProperties();
if (props != null) {
+
// First try the skin name and if it doesn't work fallback on the skin path
nextSkin: for (int s = 0; s < 2; s++) {
String skin = props.get(s == 0 ? AvdManager.AVD_INI_SKIN_NAME
@@ -885,15 +903,16 @@ final class AvdCreationDialog extends GridDialog {
mProperties.remove(AvdManager.AVD_INI_SNAPSHOT_PRESENT);
mProperties.remove(AvdManager.AVD_INI_IMAGES_1);
mProperties.remove(AvdManager.AVD_INI_IMAGES_2);
+ mProperties.remove(AvdManager.AVD_INI_DEVICE_MANUFACTURER);
+ mProperties.remove(AvdManager.AVD_INI_DEVICE_NAME);
mHardwareViewer.refresh();
}
// Sets all of the other options based on the device currently selected in mDeviceCombo
private void prefillWithDeviceConfig() {
- int index = mDeviceCombo.getSelectionIndex();
- if (index >= 0 && index < mDeviceList.size()){
- Device d = mDeviceList.get(index);
+ Device d = getSelectedDevice();
+ if (d != null) {
Hardware hw = d.getDefaultHardware();
// Try setting the CPU/ABI
@@ -1042,10 +1061,22 @@ final class AvdCreationDialog extends GridDialog {
private void reloadDeviceCombo() {
+ Device selectedDevice = getSelectedDevice();
+
+ mDeviceCombo.removeAll();
for (Device d : mDeviceList) {
mDeviceCombo.add(d.getManufacturer() + " " + d.getName());
}
- mDeviceCombo.setEnabled(true);
+
+ // Try to select the previously selected device if it still exists
+ if (selectedDevice != null) {
+ int index = mDeviceList.indexOf(selectedDevice);
+ if (index >= 0) {
+ mDeviceCombo.select(index);
+ }
+ }
+
+ mDeviceCombo.setEnabled(mTargetCombo.getSelectionIndex() >= 0);
}
private void reloadSkinCombo() {
@@ -1392,6 +1423,15 @@ final class AvdCreationDialog extends GridDialog {
return false;
}
+ targetIndex = mDeviceCombo.getSelectionIndex();
+ if (targetIndex >= 0 && targetIndex < mDeviceList.size()) {
+ Device d = mDeviceList.get(targetIndex);
+ // Set the properties so it gets saved to the avd's ini
+ mProperties.put(AvdManager.AVD_INI_DEVICE_MANUFACTURER, d.getManufacturer());
+ mProperties.put(AvdManager.AVD_INI_DEVICE_NAME, d.getName());
+ }
+
+
// resolve the target.
String targetName = mTargetCombo.getItem(targetIndex);
IAndroidTarget target = mCurrentTargets.get(targetName);
@@ -1492,6 +1532,10 @@ final class AvdCreationDialog extends GridDialog {
success = avdInfo != null;
+ // Remove the device name and manufacturer properties so they don't show up in the hardware list
+ mProperties.remove(AvdManager.AVD_INI_DEVICE_MANUFACTURER);
+ mProperties.remove(AvdManager.AVD_INI_DEVICE_NAME);
+
if (log instanceof MessageBoxLog) {
((MessageBoxLog) log).displayResult(success);
}
@@ -1524,6 +1568,15 @@ final class AvdCreationDialog extends GridDialog {
return new ISystemImage[0];
}
+ private Device getSelectedDevice() {
+ int targetIndex = mDeviceCombo.getSelectionIndex();
+ if (targetIndex >= 0 && mDeviceList.size() > targetIndex){
+ return mDeviceList.get(targetIndex);
+ } else {
+ return null;
+ }
+ }
+
// End of hiding from SWT Designer
//$hide<<$
}