diff options
12 files changed, 368 insertions, 77 deletions
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 8c37cc6..b6f9a09 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 @@ -591,6 +591,9 @@ public class ConfigurationComposite extends Composite { ConfigManagerDialog dialog = new ConfigManagerDialog(getShell()); dialog.open(); + // save the user devices + Sdk.getCurrent().getLayoutDeviceManager().save(); + // reload the combo with the new content. loadDevices(); initUiWithDevices(); diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/CountryCodeQualifier.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/CountryCodeQualifier.java index f570bac..97028e9 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/CountryCodeQualifier.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/CountryCodeQualifier.java @@ -33,7 +33,7 @@ public final class CountryCodeQualifier extends ResourceQualifier { private final static Pattern sCountryCodePattern = Pattern.compile("^mcc(\\d{3})$");//$NON-NLS-1$ - private int mCode = DEFAULT_CODE; + private final int mCode; public static final String NAME = "Mobile Country Code"; @@ -56,8 +56,7 @@ public final class CountryCodeQualifier extends ResourceQualifier { return null; } - CountryCodeQualifier qualifier = new CountryCodeQualifier(); - qualifier.mCode = code; + CountryCodeQualifier qualifier = new CountryCodeQualifier(code); return qualifier; } @@ -77,6 +76,14 @@ public final class CountryCodeQualifier extends ResourceQualifier { return ""; //$NON-NLS-1$ } + public CountryCodeQualifier() { + this(DEFAULT_CODE); + } + + public CountryCodeQualifier(int code) { + mCode = code; + } + public int getCode() { return mCode; } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/NetworkCodeQualifier.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/NetworkCodeQualifier.java index 32bd667..655fe4e 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/NetworkCodeQualifier.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/NetworkCodeQualifier.java @@ -33,7 +33,7 @@ public final class NetworkCodeQualifier extends ResourceQualifier { private final static Pattern sNetworkCodePattern = Pattern.compile("^mnc(\\d{1,3})$"); //$NON-NLS-1$ - private int mCode = DEFAULT_CODE; + private final int mCode; public final static String NAME = "Mobile Network Code"; @@ -56,8 +56,7 @@ public final class NetworkCodeQualifier extends ResourceQualifier { return null; } - NetworkCodeQualifier qualifier = new NetworkCodeQualifier(); - qualifier.mCode = code; + NetworkCodeQualifier qualifier = new NetworkCodeQualifier(code); return qualifier; } @@ -77,6 +76,14 @@ public final class NetworkCodeQualifier extends ResourceQualifier { return ""; //$NON-NLS-1$ } + public NetworkCodeQualifier() { + this(DEFAULT_CODE); + } + + public NetworkCodeQualifier(int code) { + mCode = code; + } + public int getCode() { return mCode; } @@ -115,8 +122,7 @@ public final class NetworkCodeQualifier extends ResourceQualifier { return false; } - NetworkCodeQualifier qualifier = new NetworkCodeQualifier(); - qualifier.mCode = code; + NetworkCodeQualifier qualifier = new NetworkCodeQualifier(code); config.setNetworkCodeQualifier(qualifier); return true; } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDevice.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDevice.java index 89cac5b..9e80103 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDevice.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDevice.java @@ -16,11 +16,26 @@ package com.android.ide.eclipse.adt.internal.sdk; +import com.android.ide.eclipse.adt.internal.resources.configurations.CountryCodeQualifier; import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration; +import com.android.ide.eclipse.adt.internal.resources.configurations.KeyboardStateQualifier; +import com.android.ide.eclipse.adt.internal.resources.configurations.NavigationMethodQualifier; +import com.android.ide.eclipse.adt.internal.resources.configurations.NetworkCodeQualifier; +import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier; +import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenDimensionQualifier; +import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier; +import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenRatioQualifier; +import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenSizeQualifier; +import com.android.ide.eclipse.adt.internal.resources.configurations.TextInputMethodQualifier; +import com.android.ide.eclipse.adt.internal.resources.configurations.TouchScreenQualifier; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; import java.util.Collections; import java.util.HashMap; import java.util.Map; +import java.util.Map.Entry; /** * Class representing a layout device. @@ -53,6 +68,138 @@ public class LayoutDevice { mName = name; } + /** + * Saves the Layout Device into a document under a given node + * @param doc the document. + * @param parentNode the parent node. + */ + void saveTo(Document doc, Element parentNode) { + // create the device node + Element deviceNode = createNode(doc, parentNode, LayoutDevicesXsd.NODE_DEVICE); + + // create the name attribute (no namespace on this one). + deviceNode.setAttribute(LayoutDevicesXsd.ATTR_NAME, mName); + + // create a default with the x/y dpi + Element defaultNode = createNode(doc, deviceNode, LayoutDevicesXsd.NODE_DEFAULT); + if (Float.isNaN(mXDpi) == false) { + Element xdpiNode = createNode(doc, defaultNode, LayoutDevicesXsd.NODE_XDPI); + xdpiNode.setTextContent(Float.toString(mXDpi)); + } + if (Float.isNaN(mYDpi) == false) { + Element xdpiNode = createNode(doc, defaultNode, LayoutDevicesXsd.NODE_YDPI); + xdpiNode.setTextContent(Float.toString(mYDpi)); + } + + // then save all the configs. + for (Entry<String, FolderConfiguration> entry : mEditMap.entrySet()) { + saveConfigTo(doc, deviceNode, entry.getKey(), entry.getValue()); + } + } + + /** + * Creates and returns a new NS-enabled node. + * @param doc the {@link Document} + * @param parentNode the parent node. The new node is appended to this one as a child. + * @param name the name of the node. + * @return the newly created node. + */ + private Element createNode(Document doc, Element parentNode, String name) { + Element newNode = doc.createElementNS( + LayoutDevicesXsd.NS_LAYOUT_DEVICE_XSD, name); + newNode.setPrefix(doc.lookupPrefix(LayoutDevicesXsd.NS_LAYOUT_DEVICE_XSD)); + parentNode.appendChild(newNode); + + return newNode; + } + + /** + * Saves a {@link FolderConfiguration} in a {@link Document}. + * @param doc the Document in which to save + * @param parent the parent node + * @param configName the name of the config + * @param config the config to save + */ + private void saveConfigTo(Document doc, Element parent, String configName, + FolderConfiguration config) { + Element configNode = createNode(doc, parent, LayoutDevicesXsd.NODE_CONFIG); + + // create the name attribute (no namespace on this one). + configNode.setAttribute(LayoutDevicesXsd.ATTR_NAME, configName); + + // now do the qualifiers + CountryCodeQualifier ccq = config.getCountryCodeQualifier(); + if (ccq != null) { + Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_COUNTRY_CODE); + node.setTextContent(Integer.toString(ccq.getCode())); + } + + NetworkCodeQualifier ncq = config.getNetworkCodeQualifier(); + if (ncq != null) { + Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_NETWORK_CODE); + node.setTextContent(Integer.toString(ncq.getCode())); + } + + ScreenSizeQualifier ssq = config.getScreenSizeQualifier(); + if (ssq != null) { + Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_SCREEN_SIZE); + node.setTextContent(ssq.getFolderSegment(null)); + } + + ScreenRatioQualifier srq = config.getScreenRatioQualifier(); + if (srq != null) { + Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_SCREEN_RATIO); + node.setTextContent(srq.getFolderSegment(null)); + } + + ScreenOrientationQualifier soq = config.getScreenOrientationQualifier(); + if (soq != null) { + Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_SCREEN_ORIENTATION); + node.setTextContent(soq.getFolderSegment(null)); + } + + PixelDensityQualifier pdq = config.getPixelDensityQualifier(); + if (pdq != null) { + Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_PIXEL_DENSITY); + node.setTextContent(pdq.getFolderSegment(null)); + } + + TouchScreenQualifier ttq = config.getTouchTypeQualifier(); + if (ttq != null) { + Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_TOUCH_TYPE); + node.setTextContent(ttq.getFolderSegment(null)); + } + + KeyboardStateQualifier ksq = config.getKeyboardStateQualifier(); + if (ksq != null) { + Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_KEYBOARD_STATE); + node.setTextContent(ksq.getFolderSegment(null)); + } + + TextInputMethodQualifier timq = config.getTextInputMethodQualifier(); + if (timq != null) { + Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_TEXT_INPUT_METHOD); + node.setTextContent(timq.getFolderSegment(null)); + } + + NavigationMethodQualifier nmq = config.getNavigationMethodQualifier(); + if (nmq != null) { + Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_NAV_METHOD); + node.setTextContent(nmq.getFolderSegment(null)); + } + + ScreenDimensionQualifier sdq = config.getScreenDimensionQualifier(); + if (sdq != null) { + Element sizeNode = createNode(doc, configNode, LayoutDevicesXsd.NODE_SCREEN_DIMENSION); + + Element node = createNode(doc, sizeNode, LayoutDevicesXsd.NODE_SIZE); + node.setTextContent(Integer.toString(sdq.getValue1())); + + node = createNode(doc, sizeNode, LayoutDevicesXsd.NODE_SIZE); + node.setTextContent(Integer.toString(sdq.getValue2())); + } + } + void addConfig(String name, FolderConfiguration config) { mEditMap.put(name, config); _seal(); diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDeviceHandler.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDeviceHandler.java index bb9a13d..7ad4e5d 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDeviceHandler.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDeviceHandler.java @@ -16,9 +16,11 @@ package com.android.ide.eclipse.adt.internal.sdk; +import com.android.ide.eclipse.adt.internal.resources.configurations.CountryCodeQualifier; import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration; import com.android.ide.eclipse.adt.internal.resources.configurations.KeyboardStateQualifier; import com.android.ide.eclipse.adt.internal.resources.configurations.NavigationMethodQualifier; +import com.android.ide.eclipse.adt.internal.resources.configurations.NetworkCodeQualifier; import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier; import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenDimensionQualifier; import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier; @@ -44,7 +46,7 @@ import java.util.List; /** * {@link DefaultHandler} implementation to parse Layout Device XML file. - * @see LayoutConfigsXsd + * @see LayoutDevicesXsd * @see Layout-configs.xsd */ class LayoutDeviceHandler extends DefaultHandler { @@ -74,17 +76,17 @@ class LayoutDeviceHandler extends DefaultHandler { @Override public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException { - if (LayoutConfigsXsd.NODE_DEVICE.equals(localName)) { + if (LayoutDevicesXsd.NODE_DEVICE.equals(localName)) { // get the deviceName, will not be null since we validated the XML. - String deviceName = attributes.getValue("", LayoutConfigsXsd.ATTR_NAME); + String deviceName = attributes.getValue("", LayoutDevicesXsd.ATTR_NAME); // create a device and add it to the list mCurrentDevice = new LayoutDevice(deviceName); mDevices.add(mCurrentDevice); - } else if (LayoutConfigsXsd.NODE_DEFAULT.equals(localName)) { + } else if (LayoutDevicesXsd.NODE_DEFAULT.equals(localName)) { // create a new default config mDefaultConfig = mCurrentConfig = new FolderConfiguration(); - } else if (LayoutConfigsXsd.NODE_CONFIG.equals(localName)) { + } else if (LayoutDevicesXsd.NODE_CONFIG.equals(localName)) { // create a new config mCurrentConfig = new FolderConfiguration(); @@ -94,11 +96,11 @@ class LayoutDeviceHandler extends DefaultHandler { } // get the name of the config - String deviceName = attributes.getValue("", LayoutConfigsXsd.ATTR_NAME); + String deviceName = attributes.getValue("", LayoutDevicesXsd.ATTR_NAME); // give it to the current device. mCurrentDevice.addConfig(deviceName, mCurrentConfig); - } else if (LayoutConfigsXsd.NODE_SCREEN_DIMENSION.equals(localName)) { + } else if (LayoutDevicesXsd.NODE_SCREEN_DIMENSION.equals(localName)) { mSize1 = mSize2 = null; } @@ -112,53 +114,61 @@ class LayoutDeviceHandler extends DefaultHandler { @Override public void endElement(String uri, String localName, String name) throws SAXException { - if (LayoutConfigsXsd.NODE_DEVICE.equals(localName)) { + if (LayoutDevicesXsd.NODE_DEVICE.equals(localName)) { mCurrentDevice = null; mDefaultConfig = null; - } else if (LayoutConfigsXsd.NODE_CONFIG.equals(localName)) { + } else if (LayoutDevicesXsd.NODE_CONFIG.equals(localName)) { mCurrentConfig = null; - } else if (LayoutConfigsXsd.NODE_SCREEN_SIZE.equals(localName)) { + } else if (LayoutDevicesXsd.NODE_COUNTRY_CODE.equals(localName)) { + CountryCodeQualifier ccq = new CountryCodeQualifier( + Integer.parseInt(mStringAccumulator.toString())); + mCurrentConfig.setCountryCodeQualifier(ccq); + } else if (LayoutDevicesXsd.NODE_NETWORK_CODE.equals(localName)) { + NetworkCodeQualifier ncq = new NetworkCodeQualifier( + Integer.parseInt(mStringAccumulator.toString())); + mCurrentConfig.setNetworkCodeQualifier(ncq); + } else if (LayoutDevicesXsd.NODE_SCREEN_SIZE.equals(localName)) { ScreenSizeQualifier ssq = new ScreenSizeQualifier( ScreenSize.getEnum(mStringAccumulator.toString())); mCurrentConfig.setScreenSizeQualifier(ssq); - } else if (LayoutConfigsXsd.NODE_SCREEN_RATIO.equals(localName)) { + } else if (LayoutDevicesXsd.NODE_SCREEN_RATIO.equals(localName)) { ScreenRatioQualifier srq = new ScreenRatioQualifier( ScreenRatio.getEnum(mStringAccumulator.toString())); mCurrentConfig.setScreenRatioQualifier(srq); - } else if (LayoutConfigsXsd.NODE_SCREEN_ORIENTATION.equals(localName)) { + } else if (LayoutDevicesXsd.NODE_SCREEN_ORIENTATION.equals(localName)) { ScreenOrientationQualifier soq = new ScreenOrientationQualifier( ScreenOrientation.getEnum(mStringAccumulator.toString())); mCurrentConfig.setScreenOrientationQualifier(soq); - } else if (LayoutConfigsXsd.NODE_PIXEL_DENSITY.equals(localName)) { + } else if (LayoutDevicesXsd.NODE_PIXEL_DENSITY.equals(localName)) { PixelDensityQualifier pdq = new PixelDensityQualifier( Density.getEnum(mStringAccumulator.toString())); mCurrentConfig.setPixelDensityQualifier(pdq); - } else if (LayoutConfigsXsd.NODE_TOUCH_TYPE.equals(localName)) { + } else if (LayoutDevicesXsd.NODE_TOUCH_TYPE.equals(localName)) { TouchScreenQualifier tsq = new TouchScreenQualifier( TouchScreenType.getEnum(mStringAccumulator.toString())); mCurrentConfig.setTouchTypeQualifier(tsq); - } else if (LayoutConfigsXsd.NODE_KEYBOARD_STATE.equals(localName)) { + } else if (LayoutDevicesXsd.NODE_KEYBOARD_STATE.equals(localName)) { KeyboardStateQualifier ksq = new KeyboardStateQualifier( KeyboardState.getEnum(mStringAccumulator.toString())); mCurrentConfig.setKeyboardStateQualifier(ksq); - } else if (LayoutConfigsXsd.NODE_TEXT_INPUT_METHOD.equals(localName)) { + } else if (LayoutDevicesXsd.NODE_TEXT_INPUT_METHOD.equals(localName)) { TextInputMethodQualifier timq = new TextInputMethodQualifier( TextInputMethod.getEnum(mStringAccumulator.toString())); mCurrentConfig.setTextInputMethodQualifier(timq); - } else if (LayoutConfigsXsd.NODE_NAV_METHOD.equals(localName)) { + } else if (LayoutDevicesXsd.NODE_NAV_METHOD.equals(localName)) { NavigationMethodQualifier nmq = new NavigationMethodQualifier( NavigationMethod.getEnum(mStringAccumulator.toString())); mCurrentConfig.setNavigationMethodQualifier(nmq); - } else if (LayoutConfigsXsd.NODE_SCREEN_DIMENSION.equals(localName)) { + } else if (LayoutDevicesXsd.NODE_SCREEN_DIMENSION.equals(localName)) { ScreenDimensionQualifier qual = ScreenDimensionQualifier.getQualifier(mSize1, mSize2); if (qual != null) { mCurrentConfig.setScreenDimensionQualifier(qual); } - } else if (LayoutConfigsXsd.NODE_XDPI.equals(localName)) { + } else if (LayoutDevicesXsd.NODE_XDPI.equals(localName)) { mCurrentDevice.setXDpi(Float.parseFloat(mStringAccumulator.toString())); - } else if (LayoutConfigsXsd.NODE_YDPI.equals(localName)) { + } else if (LayoutDevicesXsd.NODE_YDPI.equals(localName)) { mCurrentDevice.setYDpi(Float.parseFloat(mStringAccumulator.toString())); - } else if (LayoutConfigsXsd.NODE_SIZE.equals(localName)) { + } else if (LayoutDevicesXsd.NODE_SIZE.equals(localName)) { if (mSize1 == null) { mSize1 = mStringAccumulator.toString(); } else if (mSize2 == null) { diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDeviceManager.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDeviceManager.java index 03daf40..3b19f17 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDeviceManager.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDeviceManager.java @@ -18,8 +18,12 @@ package com.android.ide.eclipse.adt.internal.sdk; import com.android.ide.eclipse.adt.AdtPlugin; import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration; +import com.android.prefs.AndroidLocation; +import com.android.prefs.AndroidLocation.AndroidLocationException; import com.android.sdklib.SdkConstants; +import org.w3c.dom.Document; +import org.w3c.dom.Element; import org.xml.sax.ErrorHandler; import org.xml.sax.InputSource; import org.xml.sax.SAXException; @@ -35,10 +39,17 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; +import javax.xml.transform.Result; import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import javax.xml.validation.Validator; @@ -232,11 +243,43 @@ public class LayoutDeviceManager { } } - void load(String sdkOsLocation) { + /** + * Saves the user-made {@link LayoutDevice}s to disk. + */ + public void save() { + try { + String userFolder = AndroidLocation.getFolder(); + File deviceXml = new File(userFolder, SdkConstants.FN_DEVICES_XML); + if (deviceXml.isDirectory() == false) { + write(deviceXml, mUserLayoutDevices); + } + } catch (AndroidLocationException e) { + // no user folder? simply don't save the user layout device. + // we could display the error, but it's likely something else did before, as + // nothing will work w/o it. + AdtPlugin.log(e, "Unable to find user directory"); + } + } + + /** + * Loads the default built-in and user created Layout Devices. + * @param sdkOsLocation location of the SDK. + */ + void loadDefaultAndUserDevices(String sdkOsLocation) { // load the default devices loadDefaultLayoutDevices(sdkOsLocation); // load the user devices; + try { + String userFolder = AndroidLocation.getFolder(); + File deviceXml = new File(userFolder, SdkConstants.FN_DEVICES_XML); + if (deviceXml.isFile()) { + parseLayoutDevices(deviceXml, mUserLayoutDevices); + } + } catch (AndroidLocationException e) { + // no user folder? simply don't load the user layout device + AdtPlugin.log(e, "Unable to find user directory"); + } } void parseAddOnLayoutDevice(File deviceXml) { @@ -251,6 +294,8 @@ public class LayoutDeviceManager { /** * Does the actual parsing of a devices.xml file. + * @param deviceXml the {@link File} to load/parse. This must be an existing file. + * @param list the list in which to write the parsed {@link LayoutDevice}. */ private void parseLayoutDevices(File deviceXml, List<LayoutDevice> list) { // first we validate the XML @@ -259,7 +304,7 @@ public class LayoutDeviceManager { CaptureErrorHandler errorHandler = new CaptureErrorHandler(deviceXml.getAbsolutePath()); - Validator validator = LayoutConfigsXsd.getValidator(errorHandler); + Validator validator = LayoutDevicesXsd.getValidator(errorHandler); validator.validate(source); if (errorHandler.foundError() == false) { @@ -307,4 +352,45 @@ public class LayoutDeviceManager { mLayoutDevices = Collections.unmodifiableList(list); } + /** + * Writes the given {@link LayoutDevice}s into the given file. + * @param deviceXml the file to write. + * @param deviceList the LayoutDevice to write into the file. + */ + private void write(File deviceXml, List<LayoutDevice> deviceList) { + try { + // create a new document + DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); + docFactory.setNamespaceAware(true); + DocumentBuilder docBuilder = docFactory.newDocumentBuilder(); + Document doc = docBuilder.newDocument(); + + // create a base node + Element baseNode = doc.createElementNS( + LayoutDevicesXsd.NS_LAYOUT_DEVICE_XSD, + LayoutDevicesXsd.NODE_LAYOUT_DEVICES); + // create the prefix for the namespace + baseNode.setPrefix("d"); + doc.appendChild(baseNode); + + // fill it with the layout devices. + for (LayoutDevice device : deviceList) { + device.saveTo(doc, baseNode); + } + + // save the document to disk + // Prepare the DOM document for writing + Source source = new DOMSource(doc); + + // Prepare the output file + File file = new File(deviceXml.getAbsolutePath()); + Result result = new StreamResult(file); + + // Write the DOM document to the file + Transformer xformer = TransformerFactory.newInstance().newTransformer(); + xformer.transform(source, result); + } catch (Exception e) { + AdtPlugin.log(e, "Failed to write %s", deviceXml.getAbsolutePath()); + } + } } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutConfigsXsd.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDevicesXsd.java index c75c15e..67e9718 100755 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutConfigsXsd.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDevicesXsd.java @@ -31,14 +31,14 @@ import javax.xml.validation.Validator; /**
* Public constants for the layout device description XML Schema.
*/
-public class LayoutConfigsXsd {
+public class LayoutDevicesXsd {
/** The XML namespace of the layout-configs XML. */
- public static final String NS_LAYOUT_CONFIG_XSD =
- "http://schemas.android.com/sdk/android/layout-configs/1"; //$NON-NLS-1$
+ public static final String NS_LAYOUT_DEVICE_XSD =
+ "http://schemas.android.com/sdk/android/layout-devices/1"; //$NON-NLS-1$
/**
- * The "layout-configs" element is the root element of this schema.
+ * The "layout-devices" element is the root element of this schema.
*
* It must contain one or more "device" elements that each define the configurations
* available for a given device.
@@ -46,7 +46,7 @@ public class LayoutConfigsXsd { * These definitions are used in the Graphical Layout Editor in the
* Android Development Tools (ADT) plugin for Eclipse.
*/
- public static final String NODE_LAYOUT_CONFIGS = "layout-configs"; //$NON-NLS-1$
+ public static final String NODE_LAYOUT_DEVICES = "layout-devices"; //$NON-NLS-1$
/**
* A device element must contain at most one "default" element followed
@@ -76,6 +76,10 @@ public class LayoutConfigsXsd { public static final String NODE_CONFIG = "config"; //$NON-NLS-1$
+ public static final String NODE_COUNTRY_CODE = "country-code"; //$NON-NLS-1$
+
+ public static final String NODE_NETWORK_CODE = "network-code"; //$NON-NLS-1$
+
public static final String NODE_SCREEN_SIZE = "screen-size"; //$NON-NLS-1$
public static final String NODE_SCREEN_RATIO = "screen-ratio"; //$NON-NLS-1$
@@ -111,7 +115,7 @@ public class LayoutConfigsXsd { * Helper to get an input stream of the layout config XML schema.
*/
public static InputStream getXsdStream() {
- return LayoutConfigsXsd.class.getResourceAsStream("layout-configs.xsd"); //$NON-NLS-1$
+ return LayoutDevicesXsd.class.getResourceAsStream("layout-devices.xsd"); //$NON-NLS-1$
}
/** Helper method that returns a {@link Validator} for our XSD */
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 6a8bd5b..45ff31f 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 @@ -440,7 +440,7 @@ public class Sdk implements IProjectListener { SdkConstants.OS_SDK_DOCS_FOLDER); // load the built-in and user layout devices - mLayoutDeviceManager.load(mManager.getLocation()); + mLayoutDeviceManager.loadDefaultAndUserDevices(mManager.getLocation()); // and the ones from the add-on loadLayoutDevices(); } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/layout-configs.xsd b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/layout-devices.xsd index 49131fb..8a58560 100755 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/layout-configs.xsd +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/layout-devices.xsd @@ -15,17 +15,17 @@ * limitations under the License. --> <xsd:schema - targetNamespace="http://schemas.android.com/sdk/android/layout-configs/1" + targetNamespace="http://schemas.android.com/sdk/android/layout-devices/1" xmlns:xsd="http://www.w3.org/2001/XMLSchema" - xmlns:c="http://schemas.android.com/sdk/android/layout-configs/1" + xmlns:c="http://schemas.android.com/sdk/android/layout-devices/1" elementFormDefault="qualified" attributeFormDefault="unqualified" version="1"> - <xsd:element name="layout-configs"> + <xsd:element name="layout-devices"> <xsd:annotation> <xsd:documentation xml:lang="en"> - The "layout-configs" element is the root element of this schema. + The "layout-devices" element is the root element of this schema. It must contain one or more "device" elements that each define the configurations available for a given device. @@ -37,7 +37,7 @@ <xsd:complexType> <xsd:sequence> - <!-- layout-configs defines a sequence of 1..n device elements. --> + <!-- layout-devices defines a sequence of 1..n device elements. --> <xsd:element name="device" minOccurs="1" maxOccurs="unbounded"> <xsd:annotation> @@ -92,6 +92,34 @@ <xsd:all> <!-- parametersType says that 0..1 of each of these elements must be declared. --> + <xsd:element name="country-code" minOccurs="0"> + <xsd:annotation> + <xsd:documentation xml:lang="en"> + Specifies the configuration is for a particular Mobile Country Code. + </xsd:documentation> + </xsd:annotation> + <xsd:simpleType> + <xsd:restriction base="xsd:float"> + <xsd:minInclusive value="100" /> + <xsd:maxInclusive value="999" /> + </xsd:restriction> + </xsd:simpleType> + </xsd:element> + + <xsd:element name="network-code" minOccurs="0"> + <xsd:annotation> + <xsd:documentation xml:lang="en"> + Specifies the configuration is for a particular Mobile Network Code. + </xsd:documentation> + </xsd:annotation> + <xsd:simpleType> + <xsd:restriction base="xsd:float"> + <xsd:minExclusive value="0" /> + <xsd:maxExclusive value="1000" /> + </xsd:restriction> + </xsd:simpleType> + </xsd:element> + <xsd:element name="screen-size" minOccurs="0"> <xsd:annotation> <xsd:documentation xml:lang="en"> diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/sdk/TestLayoutConfisXsd.java b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/sdk/TestLayoutDevicesXsd.java index 43b0507..8aa8ee0 100755 --- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/sdk/TestLayoutConfisXsd.java +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/sdk/TestLayoutDevicesXsd.java @@ -30,9 +30,9 @@ import javax.xml.validation.Validator; import junit.framework.TestCase;
/**
- * Tests local validation of a Layout-Configs sample XMLs using an XML Schema validator.
+ * Tests local validation of a Layout-Devices sample XMLs using an XML Schema validator.
*/
-public class TestLayoutConfisXsd extends TestCase {
+public class TestLayoutDevicesXsd extends TestCase {
@Override
protected void setUp() throws Exception {
@@ -117,7 +117,7 @@ public class TestLayoutConfisXsd extends TestCase { Source source = new StreamSource(new StringReader(document));
// don't capture the validator errors, we want it to fail and catch the exception
- Validator validator = LayoutConfigsXsd.getValidator(null);
+ Validator validator = LayoutDevicesXsd.getValidator(null);
try {
validator.validate(source);
} catch (SAXParseException e) {
@@ -133,7 +133,7 @@ public class TestLayoutConfisXsd extends TestCase { Source source = new StreamSource(new StringReader(document));
CaptureErrorHandler handler = new CaptureErrorHandler();
- Validator validator = LayoutConfigsXsd.getValidator(null);
+ Validator validator = LayoutDevicesXsd.getValidator(null);
validator.validate(source);
handler.verify();
}
@@ -144,11 +144,11 @@ public class TestLayoutConfisXsd extends TestCase { public void testValidateLocalRepositoryFile() throws Exception {
InputStream xmlStream =
- TestLayoutConfisXsd.class.getResourceAsStream("config_sample.xml");
+ TestLayoutDevicesXsd.class.getResourceAsStream("config_sample.xml");
Source source = new StreamSource(xmlStream);
CaptureErrorHandler handler = new CaptureErrorHandler();
- Validator validator = LayoutConfigsXsd.getValidator(handler);
+ Validator validator = LayoutDevicesXsd.getValidator(handler);
validator.validate(source);
handler.verify();
}
@@ -168,9 +168,9 @@ public class TestLayoutConfisXsd extends TestCase { checkFailure(
// document
"<?xml version=\"1.0\"?>" +
- "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +
+ "<d:layout-devices xmlns:d=\"http://schemas.android.com/sdk/android/layout-devices/1\" >" +
"<d:unknown />" +
- "</d:layout-configs>",
+ "</d:layout-devices>",
// expected failure
"cvc-complex-type.2.4.a: Invalid content was found.*");
@@ -181,9 +181,9 @@ public class TestLayoutConfisXsd extends TestCase { checkFailure(
// document
"<?xml version=\"1.0\"?>" +
- "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +
+ "<d:layout-devices xmlns:d=\"http://schemas.android.com/sdk/android/layout-devices/1\" >" +
"<d:device />" +
- "</d:layout-configs>",
+ "</d:layout-devices>",
// expected failure
"cvc-complex-type.4: Attribute 'name' must appear on element 'd:device'.");
@@ -194,10 +194,10 @@ public class TestLayoutConfisXsd extends TestCase { checkFailure(
// document
"<?xml version=\"1.0\"?>" +
- "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" />",
+ "<d:layout-devices xmlns:d=\"http://schemas.android.com/sdk/android/layout-devices/1\" />",
// expected failure
- "cvc-complex-type.2.4.b: The content of element 'd:layout-configs' is not complete.*");
+ "cvc-complex-type.2.4.b: The content of element 'd:layout-devices' is not complete.*");
}
/** A document with an empty device element is not valid. */
@@ -205,9 +205,9 @@ public class TestLayoutConfisXsd extends TestCase { checkFailure(
// document
"<?xml version=\"1.0\"?>" +
- "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +
+ "<d:layout-devices xmlns:d=\"http://schemas.android.com/sdk/android/layout-devices/1\" >" +
"<d:device name=\"foo\"/>" +
- "</d:layout-configs>",
+ "</d:layout-devices>",
// expected failure
"cvc-complex-type.2.4.b: The content of element 'd:device' is not complete.*");
@@ -218,12 +218,12 @@ public class TestLayoutConfisXsd extends TestCase { checkFailure(
// document
"<?xml version=\"1.0\"?>" +
- "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +
+ "<d:layout-devices xmlns:d=\"http://schemas.android.com/sdk/android/layout-devices/1\" >" +
"<d:device name=\"foo\">" +
" <d:default />" +
" <d:default />" +
"</d:device>" +
- "</d:layout-configs>",
+ "</d:layout-devices>",
// expected failure
"cvc-complex-type.2.4.a: Invalid content was found starting with element 'd:default'.*");
@@ -234,12 +234,12 @@ public class TestLayoutConfisXsd extends TestCase { checkFailure(
// document
"<?xml version=\"1.0\"?>" +
- "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +
+ "<d:layout-devices xmlns:d=\"http://schemas.android.com/sdk/android/layout-devices/1\" >" +
"<d:device name=\"foo\">" +
" <d:config name=\"must-be-after-default\" />" +
" <d:default />" +
"</d:device>" +
- "</d:layout-configs>",
+ "</d:layout-devices>",
// expected failure
"cvc-complex-type.2.4.a: Invalid content was found starting with element 'd:default'.*");
@@ -250,13 +250,13 @@ public class TestLayoutConfisXsd extends TestCase { checkFailure(
// document
"<?xml version=\"1.0\"?>" +
- "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +
+ "<d:layout-devices xmlns:d=\"http://schemas.android.com/sdk/android/layout-devices/1\" >" +
"<d:device name=\"foo\">" +
" <d:default>" +
" <d:screen-dimension> <d:size>0</d:size> <d:size>1</d:size> </d:screen-dimension>" +
" </d:default>" +
"</d:device>" +
- "</d:layout-configs>",
+ "</d:layout-devices>",
// expected failure
"cvc-minInclusive-valid: Value '0' is not facet-valid with respect to minInclusive '1'.*");
@@ -267,13 +267,13 @@ public class TestLayoutConfisXsd extends TestCase { checkFailure(
// document
"<?xml version=\"1.0\"?>" +
- "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +
+ "<d:layout-devices xmlns:d=\"http://schemas.android.com/sdk/android/layout-devices/1\" >" +
"<d:device name=\"foo\">" +
" <d:default>" +
" <d:screen-dimension> <d:size>-5</d:size> <d:size>1</d:size> </d:screen-dimension>" +
" </d:default>" +
"</d:device>" +
- "</d:layout-configs>",
+ "</d:layout-devices>",
// expected failure
"cvc-minInclusive-valid: Value '-5' is not facet-valid with respect to minInclusive '1'.*");
@@ -284,13 +284,13 @@ public class TestLayoutConfisXsd extends TestCase { checkFailure(
// document
"<?xml version=\"1.0\"?>" +
- "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +
+ "<d:layout-devices xmlns:d=\"http://schemas.android.com/sdk/android/layout-devices/1\" >" +
"<d:device name=\"foo\">" +
" <d:default>" +
" <d:xdpi>0</d:xdpi>" +
" </d:default>" +
"</d:device>" +
- "</d:layout-configs>",
+ "</d:layout-devices>",
// expected failure
"cvc-minExclusive-valid: Value '0' is not facet-valid with respect to minExclusive '0.0E1'.*");
@@ -302,13 +302,13 @@ public class TestLayoutConfisXsd extends TestCase { checkFailure(
// document
"<?xml version=\"1.0\"?>" +
- "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +
+ "<d:layout-devices xmlns:d=\"http://schemas.android.com/sdk/android/layout-devices/1\" >" +
"<d:device name=\"foo\">" +
" <d:default>" +
" <d:xdpi>-3.1415926538</d:xdpi>" +
" </d:default>" +
"</d:device>" +
- "</d:layout-configs>",
+ "</d:layout-devices>",
// expected failure
"cvc-minExclusive-valid: Value '-3.1415926538' is not facet-valid with respect to minExclusive '0.0E1'.*");
@@ -319,13 +319,13 @@ public class TestLayoutConfisXsd extends TestCase { checkSuccess(
// document
"<?xml version=\"1.0\"?>" +
- "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +
+ "<d:layout-devices xmlns:d=\"http://schemas.android.com/sdk/android/layout-devices/1\" >" +
"<d:device name=\"foo\">" +
" <d:config name='foo'>" +
" <d:screen-ratio> \n long \r </d:screen-ratio>" +
" </d:config>" +
"</d:device>" +
- "</d:layout-configs>");
+ "</d:layout-devices>");
}
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/sdk/config_sample.xml b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/sdk/config_sample.xml index 901dd71..56a753f 100755 --- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/sdk/config_sample.xml +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/sdk/config_sample.xml @@ -14,9 +14,9 @@ * See the License for the specific language governing permissions and
* limitations under the License.
-->
-<d:layout-configs
+<d:layout-devices
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:d="http://schemas.android.com/sdk/android/layout-configs/1">
+ xmlns:d="http://schemas.android.com/sdk/android/layout-devices/1">
<d:device name="MyDevice"> <!-- 1..n -->
<d:default> <!-- 0..1 -->
@@ -134,4 +134,4 @@ </d:config>
</d:device>
-</d:layout-configs>
+</d:layout-devices>
diff --git a/scripts/devices.xml b/scripts/devices.xml index e600a19..2d10b89 100644 --- a/scripts/devices.xml +++ b/scripts/devices.xml @@ -1,7 +1,7 @@ <?xml version="1.0"?> -<d:layout-configs +<d:layout-devices xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns:d="http://schemas.android.com/sdk/android/layout-configs/1"> + xmlns:d="http://schemas.android.com/sdk/android/layout-devices/1"> <d:device name="ADP1"> <d:default> @@ -59,4 +59,4 @@ <d:screen-orientation>land</d:screen-orientation> </d:config> </d:device> -</d:layout-configs> +</d:layout-devices> |
