diff options
author | Android (Google) Code Review <android-gerrit@google.com> | 2009-08-11 18:44:08 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2009-08-11 18:44:08 -0700 |
commit | 4b94cdff020a67cb4683f1f1200b1f2752e6a9ac (patch) | |
tree | efc31e76e0a6d32348209b085c1e44a19684bc2a | |
parent | 0a2bc40de84741f177d13e0140385a3bd31276a2 (diff) | |
parent | bb42ea097ccb1821917aba1bed519661c37462b7 (diff) | |
download | sdk-4b94cdff020a67cb4683f1f1200b1f2752e6a9ac.zip sdk-4b94cdff020a67cb4683f1f1200b1f2752e6a9ac.tar.gz sdk-4b94cdff020a67cb4683f1f1200b1f2752e6a9ac.tar.bz2 |
Merge change 20866 into donut
* changes:
Make the res qualifiers aware of the project target to handle differnt behavior.
20 files changed, 755 insertions, 638 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/GraphicalLayoutEditor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/GraphicalLayoutEditor.java index c940b9f..225d5bd 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/GraphicalLayoutEditor.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/GraphicalLayoutEditor.java @@ -4,7 +4,7 @@ * 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 @@ -43,6 +43,7 @@ import com.android.ide.eclipse.adt.internal.resources.configurations.TextInputMe import com.android.ide.eclipse.adt.internal.resources.configurations.TouchScreenQualifier; import com.android.ide.eclipse.adt.internal.resources.configurations.KeyboardStateQualifier.KeyboardState; import com.android.ide.eclipse.adt.internal.resources.configurations.NavigationMethodQualifier.NavigationMethod; +import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier.Density; import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier.ScreenOrientation; import com.android.ide.eclipse.adt.internal.resources.configurations.TextInputMethodQualifier.TextInputMethod; import com.android.ide.eclipse.adt.internal.resources.configurations.TouchScreenQualifier.TouchScreenType; @@ -55,7 +56,6 @@ import com.android.ide.eclipse.adt.internal.sdk.LoadStatus; import com.android.ide.eclipse.adt.internal.sdk.Sdk; import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData.LayoutBridge; import com.android.ide.eclipse.adt.internal.sdk.Sdk.ITargetChangeListener; -import com.android.ide.eclipse.adt.internal.ui.ConfigurationSelector.DensityVerifier; import com.android.ide.eclipse.adt.internal.ui.ConfigurationSelector.DimensionVerifier; import com.android.ide.eclipse.adt.internal.ui.ConfigurationSelector.LanguageRegionVerifier; import com.android.ide.eclipse.adt.internal.ui.ConfigurationSelector.MobileCodeVerifier; @@ -143,7 +143,7 @@ import java.util.Set; */ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor implements ILayoutReloadListener { - + private final static String THEME_SEPARATOR = "----------"; //$NON-NLS-1$ /** Reference to the layout editor */ @@ -161,7 +161,7 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor private Combo mLanguage; private Combo mRegion; private Combo mOrientation; - private Text mDensity; + private Combo mDensity; private Combo mTouch; private Combo mKeyboard; private Combo mTextInput; @@ -216,7 +216,7 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor public void onTargetsLoaded() { // because the SDK changed we must reset the configured framework resource. mConfiguredFrameworkRes = null; - + updateUIFromResources(); mThemeCombo.getParent().layout(); @@ -383,19 +383,19 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor new Label(topParent, SWT.NONE).setText("Density"); mDensityIcon = createControlComposite(topParent, true /* grab_horizontal */); - mDensity = new Text(mDensityIcon.getParent(), SWT.BORDER); + mDensity = new Combo(mDensityIcon.getParent(), SWT.DROP_DOWN | SWT.READ_ONLY); + Density[] dValues = Density.values(); + mDensity.add("(Default)"); + for (Density value : dValues) { + mDensity.add(value.getDisplayValue()); + } + mDensity.select(0); mDensity.setLayoutData(new GridData( GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL)); - mDensity.addVerifyListener(new DensityVerifier()); mDensity.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetDefaultSelected(SelectionEvent e) { - onDensityChange(); - } - }); - mDensity.addModifyListener(new ModifyListener() { - public void modifyText(ModifyEvent e) { - onDensityChange(); + @Override + public void widgetSelected(SelectionEvent e) { + onDensityChange(); } }); @@ -468,7 +468,7 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor @Override public void widgetSelected(SelectionEvent e) { onNavigationChange(); - } + } }); Composite labelParent = new Composite(topParent, SWT.NONE); @@ -512,7 +512,7 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor mSize1.addSelectionListener(sl); mSize2.addSelectionListener(sl); - + ModifyListener sizeModifyListener = new ModifyListener() { public void modifyText(ModifyEvent e) { onSizeChange(); @@ -551,11 +551,12 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor @Override public void widgetSelected(SelectionEvent e) { LayoutCreatorDialog dialog = new LayoutCreatorDialog(mCreateButton.getShell(), - mEditedFile.getName(), mCurrentConfig); + mEditedFile.getName(), + Sdk.getCurrent().getTarget(mEditedFile.getProject()), mCurrentConfig); if (dialog.open() == Dialog.OK) { final FolderConfiguration config = new FolderConfiguration(); dialog.getConfiguration(config); - + createAlternateLayout(config); } } @@ -591,7 +592,7 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor @Override protected PaletteRoot getPaletteRoot() { mPaletteRoot = PaletteFactory.createPaletteRoot(mPaletteRoot, - mLayoutEditor.getTargetData()); + mLayoutEditor.getTargetData()); return mPaletteRoot; } @@ -618,7 +619,7 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor getCommandStack().markSaveLocation(); firePropertyChange(PROP_DIRTY); } - + @Override protected void configurePaletteViewer() { super.configurePaletteViewer(); @@ -628,7 +629,7 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor // the PaletteTemplateEntry held in the PaletteRoot. TemplateTransferDragSourceListener dragSource = new TemplateTransferDragSourceListener(getPaletteViewer()); - + // Create a drag source on the palette viewer. // See the drag target associated with the GraphicalViewer in configureGraphicalViewer. getPaletteViewer().addDragSourceListener(dragSource); @@ -645,12 +646,12 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor viewer.setEditPartFactory(new UiElementsEditPartFactory(mParent.getDisplay())); viewer.setRootEditPart(new ScalableFreeformRootEditPart()); - // Disable the following -- we don't drag *from* the GraphicalViewer yet: + // Disable the following -- we don't drag *from* the GraphicalViewer yet: // viewer.addDragSourceListener(new TemplateTransferDragSourceListener(viewer)); - + viewer.addDropTargetListener(new DropListener(viewer)); } - + class DropListener extends TemplateTransferDropTargetListener { public DropListener(EditPartViewer viewer) { super(viewer); @@ -670,7 +671,7 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor public Object getObjectType() { return template; } - + }; } } @@ -698,7 +699,7 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor input.toString()); } } - + /* (non-javadoc) * Sets the graphicalViewer for this EditorPart. * @param viewer the graphical viewer @@ -714,18 +715,18 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor /** * Used by LayoutEditor.UiEditorActions.selectUiNode to select a new UI Node * created by {@link ElementCreateCommand#execute()}. - * + * * @param uiNodeModel The {@link UiElementNode} to select. */ @Override void selectModel(UiElementNode uiNodeModel) { GraphicalViewer viewer = getGraphicalViewer(); - + // Give focus to the graphical viewer (in case the outline has it) viewer.getControl().forceFocus(); - + Object editPart = viewer.getEditPartRegistry().get(uiNodeModel); - + if (editPart instanceof EditPart) { viewer.select((EditPart)editPart); } @@ -745,7 +746,7 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor MenuManager menuManager = new MenuManager(); menuManager.setRemoveAllWhenShown(true); menuManager.addMenuListener(new ActionMenuListener(viewer)); - + return menuManager; } @@ -775,13 +776,13 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor } } } - + if (selected.size() > 0) { doCreateMenuAction(manager, mViewer, selected); } } } - + private void doCreateMenuAction(IMenuManager manager, final GraphicalViewer viewer, final ArrayList<UiElementNode> selected) { @@ -820,7 +821,7 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor // Append "add" and "remove" actions. They do the same thing as the add/remove // buttons on the side. IconFactory factory = IconFactory.getInstance(); - + final UiEditorActions uiActions = mLayoutEditor.getUiEditorActions(); // "Add" makes sense only if there's 0 or 1 item selected since the @@ -845,7 +846,7 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor }); manager.add(new Separator()); - + manager.add(new Action("Up", factory.getImageDescriptor("up")) { //$NON-NLS-2$ @Override public void run() { @@ -859,8 +860,8 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor } }); } - - } + + } /** * Sets the UI for the edition of a new file. @@ -870,11 +871,11 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor void editNewFile(FolderConfiguration configuration) { // update the configuration UI setConfiguration(configuration, true /*force*/); - + // enable the create button if the current and edited config are not equals mCreateButton.setEnabled(mEditedConfig.equals(mCurrentConfig) == false); } - + public Rectangle getBounds() { ScreenOrientation orientation = null; if (mOrientation.getSelectionIndex() == 0) { @@ -916,7 +917,7 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor return new Rectangle(0, 0, s1, s1); } } - + /** * Renders an Android View described by a {@link ViewElementDescriptor}. * <p/>This uses the <code>wrap_content</code> mode for both <code>layout_width</code> and @@ -928,17 +929,17 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor if (mEditedFile == null) { return null; } - + IAndroidTarget target = Sdk.getCurrent().getTarget(mEditedFile.getProject()); if (target == null) { return null; } - + AndroidTargetData data = Sdk.getCurrent().getTargetData(target); if (data == null) { return null; } - + LayoutBridge bridge = data.getLayoutBridge(); if (bridge.bridge != null) { // bridge can never be null. @@ -961,7 +962,7 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor // get the project resource values based on the current config mConfiguredProjectRes = projectRes.getConfiguredResources(mCurrentConfig); } - + configuredProjectResources = mConfiguredProjectRes; } else { // we absolutely need a Map of configured project resources. @@ -998,12 +999,12 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor int height = result.getRootView().getBottom(); Raster raster = largeImage.getData(new java.awt.Rectangle(width, height)); int[] imageDataBuffer = ((DataBufferInt)raster.getDataBuffer()).getData(); - + ImageData imageData = new ImageData(width, height, 32, new PaletteData(0x00FF0000, 0x0000FF00, 0x000000FF)); imageData.setPixels(0, 0, imageDataBuffer.length, imageDataBuffer, 0); - + return imageData; } } @@ -1046,7 +1047,7 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor mNeedsXmlReload = true; } } - + /** * Actually performs the XML reload * @see #onXmlModelChanged() @@ -1054,17 +1055,17 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor private void doXmlReload(boolean force) { if (force || mNeedsXmlReload) { GraphicalViewer viewer = getGraphicalViewer(); - + // try to preserve the selection before changing the content SelectionManager selMan = viewer.getSelectionManager(); ISelection selection = selMan.getSelection(); - + try { viewer.setContents(getModel()); } finally { selMan.setSelection(selection); } - + mNeedsXmlReload = false; } } @@ -1148,12 +1149,13 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor mDensityIcon.setImage(mMatchImage); PixelDensityQualifier densityQualifier = config.getPixelDensityQualifier(); if (densityQualifier != null) { - mDensity.setText(String.format("%1$d", densityQualifier.getValue())); + mDensity.select( + Density.getIndex(densityQualifier.getValue()) + 1); mCurrentConfig.setPixelDensityQualifier(densityQualifier); } else if (force) { - mDensity.setText(""); //$NON-NLS-1$ + mOrientation.select(0); mCurrentConfig.setPixelDensityQualifier(null); - } else if (mDensity.getText().length() > 0) { + } else if (mDensity.getSelectionIndex() != 0) { mDensityIcon.setImage(mWarningImage); } @@ -1223,10 +1225,10 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor // update the string showing the folder name String current = config.toDisplayString(); mCurrentLayoutLabel.setText(current != null ? current : "(Default)"); - + mDisableUpdates = false; } - + /** * Displays an error icon in front of all the non-null qualifiers. */ @@ -1236,44 +1238,44 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor if (countryQualifier != null) { mCountryIcon.setImage(mErrorImage); } - + mNetworkIcon.setImage(mMatchImage); NetworkCodeQualifier networkQualifier = mCurrentConfig.getNetworkCodeQualifier(); if (networkQualifier != null) { mNetworkIcon.setImage(mErrorImage); } - + mLanguageIcon.setImage(mMatchImage); LanguageQualifier languageQualifier = mCurrentConfig.getLanguageQualifier(); if (languageQualifier != null) { mLanguageIcon.setImage(mErrorImage); } - + mRegionIcon.setImage(mMatchImage); RegionQualifier regionQualifier = mCurrentConfig.getRegionQualifier(); if (regionQualifier != null) { mRegionIcon.setImage(mErrorImage); } - + mOrientationIcon.setImage(mMatchImage); ScreenOrientationQualifier orientationQualifier = mCurrentConfig.getScreenOrientationQualifier(); if (orientationQualifier != null) { mOrientationIcon.setImage(mErrorImage); } - + mDensityIcon.setImage(mMatchImage); PixelDensityQualifier densityQualifier = mCurrentConfig.getPixelDensityQualifier(); if (densityQualifier != null) { mDensityIcon.setImage(mErrorImage); } - + mTouchIcon.setImage(mMatchImage); TouchScreenQualifier touchQualifier = mCurrentConfig.getTouchTypeQualifier(); if (touchQualifier != null) { mTouchIcon.setImage(mErrorImage); } - + mKeyboardIcon.setImage(mMatchImage); KeyboardStateQualifier keyboardQualifier = mCurrentConfig.getKeyboardStateQualifier(); if (keyboardQualifier != null) { @@ -1285,20 +1287,20 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor if (inputQualifier != null) { mTextInputIcon.setImage(mErrorImage); } - + mNavigationIcon.setImage(mMatchImage); NavigationMethodQualifier navigationQualifiter = mCurrentConfig.getNavigationMethodQualifier(); if (navigationQualifiter != null) { mNavigationIcon.setImage(mErrorImage); } - + mSizeIcon.setImage(mMatchImage); ScreenDimensionQualifier sizeQualifier = mCurrentConfig.getScreenDimensionQualifier(); if (sizeQualifier != null) { mSizeIcon.setImage(mErrorImage); } - + // update the string showing the folder name String current = mCurrentConfig.toDisplayString(); mCurrentLayoutLabel.setText(current != null ? current : "(Default)"); @@ -1308,7 +1310,7 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor UiDocumentNode getModel() { return mLayoutEditor.getUiRootNode(); } - + @Override void reloadPalette() { PaletteFactory.createPaletteRoot(mPaletteRoot, mLayoutEditor.getTargetData()); @@ -1474,36 +1476,12 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor } private void onDensityChange() { - // because mDensity triggers onDensityChange at each modification, calling setText() - // will trigger notifications, and we don't want that. - if (mDisableUpdates == true) { - return; - } - - // update the current config - String value = mDensity.getText(); - - // empty string, means no qualifier. - if (value.length() == 0) { - mCurrentConfig.setPixelDensityQualifier(null); + int index = mDensity.getSelectionIndex(); + if (index != 0) { + mCurrentConfig.setPixelDensityQualifier((new PixelDensityQualifier( + Density.getByIndex(index-1)))); } else { - try { - PixelDensityQualifier qualifier = PixelDensityQualifier.getQualifier( - PixelDensityQualifier.getFolderSegment(Integer.parseInt(value))); - if (qualifier != null) { - mCurrentConfig.setPixelDensityQualifier(qualifier); - } else { - // Failure! Looks like the value is wrong (for instance a one letter string). - // We do nothing in this case. - return; - } - } catch (NumberFormatException e) { - // Looks like the code is not a number. This should not happen since the text - // field has a VerifyListener that prevents it. - // We do nothing in this case. - mDensityIcon.setImage(mErrorImage); - return; - } + mCurrentConfig.setPixelDensityQualifier(null); } // look for a file to open/create @@ -1612,11 +1590,11 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor if (mEditedFile == null || mEditedConfig == null) { return; } - + // get the resources of the file's project. ProjectResources resources = ResourceManager.getInstance().getProjectResources( mEditedFile.getProject()); - + // from the resources, look for a matching file ResourceFile match = null; if (resources != null) { @@ -1643,7 +1621,7 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor // update the configuration icons with the new edited config. setConfiguration(mEditedConfig, false /*force*/); - + // enable the create button if the current and edited config are not equals mCreateButton.setEnabled(mEditedConfig.equals(mCurrentConfig) == false); @@ -1653,7 +1631,7 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor } else { // update the configuration icons with the new edited config. displayConfigError(); - + // enable the Create button mCreateButton.setEnabled(true); @@ -1661,7 +1639,8 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor String message = String.format( "No resources match the configuration\n \n\t%1$s\n \nChange the configuration or create:\n \n\tres/%2$s/%3$s\n \nYou can also click the 'Create' button above.", mCurrentConfig.toDisplayString(), - mCurrentConfig.getFolderName(ResourceFolderType.LAYOUT), + mCurrentConfig.getFolderName(ResourceFolderType.LAYOUT, + Sdk.getCurrent().getTarget(mEditedFile.getProject())), mEditedFile.getName()); showErrorInEditor(message); } @@ -1671,7 +1650,7 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor int themeIndex = mThemeCombo.getSelectionIndex(); if (themeIndex != -1) { String theme = mThemeCombo.getItem(themeIndex); - + if (theme.equals(THEME_SEPARATOR)) { mThemeCombo.select(0); } @@ -1745,7 +1724,7 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor showErrorInEditor("The project target is not set."); return; } - + AndroidTargetData data = currentSdk.getTargetData(target); if (data == null) { // It can happen that the workspace refreshes while the SDK is loading its @@ -1774,67 +1753,77 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor if (bridge.bridge != null) { // bridge can never be null. ResourceManager resManager = ResourceManager.getInstance(); - + ProjectResources projectRes = resManager.getProjectResources(iProject); if (projectRes == null) { return; } - + // get the resources of the file's project. if (mConfiguredProjectRes == null) { // make sure they are loaded projectRes.loadAll(); - + // get the project resource values based on the current config mConfiguredProjectRes = projectRes.getConfiguredResources(mCurrentConfig); } - + // get the framework resources Map<String, Map<String, IResourceValue>> frameworkResources = getConfiguredFrameworkResources(); - + if (mConfiguredProjectRes != null && frameworkResources != null) { if (mProjectCallback == null) { mProjectCallback = new ProjectCallback( bridge.classLoader, projectRes, iProject); } - + if (mLogger == null) { mLogger = new ILayoutLog() { public void error(String message) { AdtPlugin.printErrorToConsole(mEditedFile.getName(), message); } - + public void error(Throwable error) { String message = error.getMessage(); if (message == null) { message = error.getClass().getName(); } - + PrintStream ps = new PrintStream(AdtPlugin.getErrorStream()); error.printStackTrace(ps); } - + public void warning(String message) { AdtPlugin.printToConsole(mEditedFile.getName(), message); } }; } - + // get the selected theme int themeIndex = mThemeCombo.getSelectionIndex(); if (themeIndex != -1) { String theme = mThemeCombo.getItem(themeIndex); - + // Compute the layout UiElementPullParser parser = new UiElementPullParser(getModel()); Rectangle rect = getBounds(); boolean isProjectTheme = themeIndex >= mPlatformThemeCount; // FIXME pass the density/dpi from somewhere (resource config or skin). + // For now, get it from the config + int density = Density.MEDIUM.getDpiValue(); + PixelDensityQualifier qual = mCurrentConfig.getPixelDensityQualifier(); + if (qual != null) { + int d = qual.getValue().getDpiValue(); + if (d > 0) { + density = d; + } + } + ILayoutResult result = computeLayout(bridge, parser, iProject /* projectKey */, - rect.width, rect.height, 160, 160.f, 160.f, + rect.width, rect.height, density, density, density, theme, isProjectTheme, mConfiguredProjectRes, frameworkResources, mProjectCallback, mLogger); @@ -1842,20 +1831,20 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor // update the UiElementNode with the layout info. if (result.getSuccess() == ILayoutResult.SUCCESS) { model.setEditData(result.getImage()); - + updateNodeWithBounds(result.getRootView()); } else { String message = result.getErrorMessage(); - + // Reset the edit data for all the nodes. resetNodeBounds(model); - + if (message != null) { // set the error in the top element. model.setEditData(message); } } - + model.refreshUi(); } } @@ -1951,11 +1940,11 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor // clear the cache in the bridge in case a bitmap/9-patch changed. IAndroidTarget target = Sdk.getCurrent().getTarget(mEditedFile.getProject()); if (target != null) { - + AndroidTargetData data = Sdk.getCurrent().getTargetData(target); if (data != null) { LayoutBridge bridge = data.getLayoutBridge(); - + if (bridge.bridge != null) { bridge.bridge.clearCaches(mEditedFile.getProject()); } @@ -2007,28 +1996,28 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor ProjectResources frameworkProject = getFrameworkResources(); mDisableUpdates = true; - + // Reset stuff int selection = mThemeCombo.getSelectionIndex(); mThemeCombo.removeAll(); mPlatformThemeCount = 0; mLanguage.removeAll(); - + Set<String> languages = new HashSet<String>(); ArrayList<String> themes = new ArrayList<String>(); - + // get the themes, and languages from the Framework. if (frameworkProject != null) { // get the configured resources for the framework Map<String, Map<String, IResourceValue>> frameworResources = getConfiguredFrameworkResources(); - + if (frameworResources != null) { // get the styles. Map<String, IResourceValue> styles = frameworResources.get( ResourceType.STYLE.getName()); - - + + // collect the themes out of all the styles. for (IResourceValue value : styles.values()) { String name = value.getName(); @@ -2040,11 +2029,11 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor // sort them and add them to the combo Collections.sort(themes); - + for (String theme : themes) { mThemeCombo.add(theme); } - + mPlatformThemeCount = themes.size(); themes.clear(); } @@ -2054,7 +2043,7 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor languages.addAll(frameworkLanguages); } } - + // now get the themes and languages from the project. ProjectResources project = null; if (mEditedFile != null) { @@ -2062,7 +2051,7 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor // in cases where the opened file is not linked to a project, this could be null. if (project != null) { - // get the configured resources for the project + // get the configured resources for the project if (mConfiguredProjectRes == null) { // make sure they are loaded project.loadAll(); @@ -2070,12 +2059,12 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor // get the project resource values based on the current config mConfiguredProjectRes = project.getConfiguredResources(mCurrentConfig); } - + if (mConfiguredProjectRes != null) { // get the styles. Map<String, IResourceValue> styleMap = mConfiguredProjectRes.get( ResourceType.STYLE.getName()); - + if (styleMap != null) { // collect the themes out of all the styles, ie styles that extend, // directly or indirectly a platform theme. @@ -2089,9 +2078,9 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor if (mPlatformThemeCount > 0 && themes.size() > 0) { mThemeCombo.add(THEME_SEPARATOR); } - + Collections.sort(themes); - + for (String theme : themes) { mThemeCombo.add(theme); } @@ -2110,7 +2099,7 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor for (String language : languages) { mLanguage.add(language); } - + mDisableUpdates = false; // and update the Region UI based on the current language @@ -2143,7 +2132,7 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor private boolean isTheme(IResourceValue value, Map<String, IResourceValue> styleMap) { if (value instanceof IStyleResourceValue) { IStyleResourceValue style = (IStyleResourceValue)value; - + boolean frameworkStyle = false; String parentStyle = style.getParentStyle(); if (parentStyle == null) { @@ -2160,13 +2149,13 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor if (parentStyle.startsWith("@")) { parentStyle = parentStyle.substring(1); } - + // check for framework identifier. if (parentStyle.startsWith("android:")) { frameworkStyle = true; parentStyle = parentStyle.substring("android:".length()); } - + // at this point we could have the format style/<name>. we want only the name if (parentStyle.startsWith("style/")) { parentStyle = parentStyle.substring("style/".length()); @@ -2232,7 +2221,7 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor mDisableUpdates = false; } } - + private Map<String, Map<String, IResourceValue>> getConfiguredFrameworkResources() { if (mConfiguredFrameworkRes == null) { ProjectResources frameworkRes = getFrameworkResources(); @@ -2244,7 +2233,7 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor // get the framework resource values based on the current config mConfiguredFrameworkRes = frameworkRes.getConfiguredResources(mCurrentConfig); } - + return mConfiguredFrameworkRes; } @@ -2256,14 +2245,15 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor @Override protected IStatus run(IProgressMonitor monitor) { // get the folder name - String folderName = config.getFolderName(ResourceFolderType.LAYOUT); + String folderName = config.getFolderName(ResourceFolderType.LAYOUT, + Sdk.getCurrent().getTarget(mEditedFile.getProject())); try { - + // look to see if it exists. // get the res folder IFolder res = (IFolder)mEditedFile.getParent().getParent(); String path = res.getLocation().toOSString(); - + File newLayoutFolder = new File(path + File.separator + folderName); if (newLayoutFolder.isFile()) { // this should not happen since aapt would have complained @@ -2271,34 +2261,34 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor // happen. String message = String.format("File 'res/%1$s' is in the way!", folderName); - + AdtPlugin.displayError("Layout Creation", message); - + return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, message); } else if (newLayoutFolder.exists() == false) { // create it. newLayoutFolder.mkdir(); } - + // now create the file File newLayoutFile = new File(newLayoutFolder.getAbsolutePath() + File.separator + mEditedFile.getName()); newLayoutFile.createNewFile(); - + InputStream input = mEditedFile.getContents(); - + FileOutputStream fos = new FileOutputStream(newLayoutFile); - + byte[] data = new byte[512]; int count; while ((count = input.read(data)) != -1) { fos.write(data, 0, count); } - + input.close(); fos.close(); - + // refreshes the res folder to show up the new // layout folder (if needed) and the file. // We use a progress monitor to catch the end of the refresh @@ -2346,27 +2336,27 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor String message = String.format( "Failed to create File 'res/%1$s/%2$s' : %3$s", folderName, mEditedFile.getName(), e2.getMessage()); - + AdtPlugin.displayError("Layout Creation", message); - + return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, message, e2); } catch (CoreException e2) { String message = String.format( "Failed to create File 'res/%1$s/%2$s' : %3$s", folderName, mEditedFile.getName(), e2.getMessage()); - + AdtPlugin.displayError("Layout Creation", message); return e2.getStatus(); } - + return Status.OK_STATUS; } }.schedule(); } - + /** * Returns a {@link ProjectResources} for the framework resources. * @return the framework resources or null if not found. @@ -2376,10 +2366,10 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor Sdk currentSdk = Sdk.getCurrent(); if (currentSdk != null) { IAndroidTarget target = currentSdk.getTarget(mEditedFile.getProject()); - + if (target != null) { AndroidTargetData data = currentSdk.getTargetData(target); - + if (data != null) { return data.getFrameworkResources(); } @@ -2389,7 +2379,7 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor return null; } - + /** * Computes a layout by calling the correct computeLayout method of ILayoutBridge based on * the implementation API level. @@ -2402,12 +2392,12 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor Map<String, Map<String, IResourceValue>> projectResources, Map<String, Map<String, IResourceValue>> frameworkResources, IProjectCallback projectCallback, ILayoutLog logger) { - + if (bridge.apiLevel >= 3) { // newer api with boolean for separation of project/framework theme, // and density support. return bridge.bridge.computeLayout(layoutDescription, - projectKey, screenWidth, screenHeight, density, xdpi, ydpi, + projectKey, screenWidth, screenHeight, density, xdpi, ydpi, themeName, isProjectTheme, projectResources, frameworkResources, projectCallback, logger); diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutCreatorDialog.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutCreatorDialog.java index 5cd527c..a55f1d0 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutCreatorDialog.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutCreatorDialog.java @@ -22,6 +22,7 @@ import com.android.ide.eclipse.adt.internal.resources.configurations.ResourceQua import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFolderType; import com.android.ide.eclipse.adt.internal.ui.ConfigurationSelector; import com.android.ide.eclipse.adt.internal.ui.ConfigurationSelector.ConfigurationState; +import com.android.sdklib.IAndroidTarget; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.TrayDialog; @@ -40,22 +41,26 @@ class LayoutCreatorDialog extends TrayDialog { private ConfigurationSelector mSelector; private Composite mStatusComposite; - private Label mStatusLabel; + private Label mStatusLabel; private Label mStatusImage; private final FolderConfiguration mConfig = new FolderConfiguration(); private final String mFileName; + private final IAndroidTarget mTarget; /** * Creates a dialog, and init the UI from a {@link FolderConfiguration}. * @param parentShell the parent {@link Shell}. * @param config The starting configuration. */ - LayoutCreatorDialog(Shell parentShell, String fileName, FolderConfiguration config) { + LayoutCreatorDialog(Shell parentShell, String fileName, IAndroidTarget target, + FolderConfiguration config) { super(parentShell); - mFileName = fileName; - // FIXME: add some data to know what configurations already exist. + mFileName = fileName; + mTarget = target; + + // FIXME: add some data to know what configurations already exist. mConfig.set(config); } @@ -67,22 +72,22 @@ class LayoutCreatorDialog extends TrayDialog { new Label(top, SWT.NONE).setText( String.format("Configuration for the alternate version of %1$s", mFileName)); - + mSelector = new ConfigurationSelector(top); mSelector.setConfiguration(mConfig); - + // parent's layout is a GridLayout as specified in the javadoc. GridData gd = new GridData(); gd.widthHint = ConfigurationSelector.WIDTH_HINT; gd.heightHint = ConfigurationSelector.HEIGHT_HINT; mSelector.setLayoutData(gd); - + // add a listener to check on the validity of the FolderConfiguration as // they are built. mSelector.setOnChangeListener(new Runnable() { public void run() { ConfigurationState state = mSelector.getState(); - + switch (state) { case OK: mSelector.getConfiguration(mConfig); @@ -125,16 +130,16 @@ class LayoutCreatorDialog extends TrayDialog { return top; } - + public void getConfiguration(FolderConfiguration config) { config.set(mConfig); } - + /** * resets the status label to show the file that will be created. */ private void resetStatus() { mStatusLabel.setText(String.format("New File: res/%1$s/%2$s", - mConfig.getFolderName(ResourceFolderType.LAYOUT), mFileName)); + mConfig.getFolderName(ResourceFolderType.LAYOUT, mTarget), mFileName)); } } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringInputPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringInputPage.java index a3fdb7d..072b1b8 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringInputPage.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringInputPage.java @@ -420,7 +420,7 @@ class ExtractStringInputPage extends UserInputWizardPage implements IWizardPage // recreate the res path from the current configuration mConfigSelector.getConfiguration(mTempConfig); StringBuffer sb = new StringBuffer(RES_FOLDER_ABS); - sb.append(mTempConfig.getFolderName(ResourceFolderType.VALUES)); + sb.append(mTempConfig.getFolderName(ResourceFolderType.VALUES, mProject)); sb.append('/'); String newPath = sb.toString(); 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 c624035..f570bac 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 @@ -17,6 +17,7 @@ package com.android.ide.eclipse.adt.internal.resources.configurations; import com.android.ide.eclipse.adt.internal.editors.IconFactory; +import com.android.sdklib.IAndroidTarget; import org.eclipse.swt.graphics.Image; @@ -33,9 +34,9 @@ public final class CountryCodeQualifier extends ResourceQualifier { private final static Pattern sCountryCodePattern = Pattern.compile("^mcc(\\d{3})$");//$NON-NLS-1$ private int mCode = DEFAULT_CODE; - + public static final String NAME = "Mobile Country Code"; - + /** * Creates and returns a qualifier from the given folder segment. If the segment is incorrect, * <code>null</code> is returned. @@ -54,15 +55,15 @@ public final class CountryCodeQualifier extends ResourceQualifier { // looks like the string we extracted wasn't a valid number. return null; } - + CountryCodeQualifier qualifier = new CountryCodeQualifier(); qualifier.mCode = code; return qualifier; } - + return null; } - + /** * Returns the folder name segment for the given value. This is equivalent to calling * {@link #toString()} on a {@link CountryCodeQualifier} object. @@ -72,29 +73,29 @@ public final class CountryCodeQualifier extends ResourceQualifier { if (code != DEFAULT_CODE && code >= 100 && code <=999) { // code is 3 digit.) { return String.format("mcc%1$d", code); //$NON-NLS-1$ } - + return ""; //$NON-NLS-1$ } - + public int getCode() { return mCode; } - + @Override public String getName() { return NAME; } - + @Override public String getShortName() { return "Country Code"; } - + @Override public Image getIcon() { return IconFactory.getInstance().getIcon("mcc"); //$NON-NLS-1$ } - + @Override public boolean isValid() { return mCode != DEFAULT_CODE; @@ -107,29 +108,29 @@ public final class CountryCodeQualifier extends ResourceQualifier { config.setCountryCodeQualifier(qualifier); return true; } - + return false; } - + @Override public boolean equals(Object qualifier) { if (qualifier instanceof CountryCodeQualifier) { return mCode == ((CountryCodeQualifier)qualifier).mCode; } - + return false; } - + @Override public int hashCode() { return mCode; } - + /** * Returns the string used to represent this qualifier in the folder name. */ @Override - public String toString() { + public String getFolderSegment(IAndroidTarget target) { return getFolderSegment(mCode); } @@ -138,7 +139,7 @@ public final class CountryCodeQualifier extends ResourceQualifier { if (mCode != DEFAULT_CODE) { return String.format("MCC %1$d", mCode); } - + return ""; //$NON-NLS-1$ } } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/FolderConfiguration.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/FolderConfiguration.java index aea146b..ff8c26a 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/FolderConfiguration.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/FolderConfiguration.java @@ -17,6 +17,10 @@ package com.android.ide.eclipse.adt.internal.resources.configurations; import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFolderType; +import com.android.ide.eclipse.adt.internal.sdk.Sdk; +import com.android.sdklib.IAndroidTarget; + +import org.eclipse.core.resources.IProject; /** @@ -27,7 +31,7 @@ public final class FolderConfiguration implements Comparable<FolderConfiguration public final static String QUALIFIER_SEP = "-"; //$NON-NLS-1$ private final ResourceQualifier[] mQualifiers = new ResourceQualifier[INDEX_COUNT]; - + private final static int INDEX_COUNTRY_CODE = 0; private final static int INDEX_NETWORK_CODE = 1; private final static int INDEX_LANGUAGE = 2; @@ -40,7 +44,7 @@ public final class FolderConfiguration implements Comparable<FolderConfiguration private final static int INDEX_NAVIGATION_METHOD = 9; private final static int INDEX_SCREEN_DIMENSION = 10; private final static int INDEX_COUNT = 11; - + /** * Sets the config from the qualifiers of a given <var>config</var>. * @param config @@ -62,7 +66,7 @@ public final class FolderConfiguration implements Comparable<FolderConfiguration } } } - + /** * Returns the first invalid qualifier, or <code>null<code> if they are all valid (or if none * exists). @@ -73,11 +77,11 @@ public final class FolderConfiguration implements Comparable<FolderConfiguration return mQualifiers[i]; } } - + // all allocated qualifiers are valid, we return null. return null; } - + /** * Returns whether the Region qualifier is valid. Region qualifier can only be present if a * Language qualifier is present as well. @@ -90,7 +94,7 @@ public final class FolderConfiguration implements Comparable<FolderConfiguration return true; } - + /** * Adds a qualifier to the {@link FolderConfiguration} * @param qualifier the {@link ResourceQualifier} to add. @@ -120,7 +124,7 @@ public final class FolderConfiguration implements Comparable<FolderConfiguration mQualifiers[INDEX_SCREEN_DIMENSION] = qualifier; } } - + /** * Removes a given qualifier from the {@link FolderConfiguration}. * @param qualifier the {@link ResourceQualifier} to remove. @@ -133,7 +137,7 @@ public final class FolderConfiguration implements Comparable<FolderConfiguration } } } - + public void setCountryCodeQualifier(CountryCodeQualifier qualifier) { mQualifiers[INDEX_COUNTRY_CODE] = qualifier; } @@ -205,7 +209,7 @@ public final class FolderConfiguration implements Comparable<FolderConfiguration public TextInputMethodQualifier getTextInputMethodQualifier() { return (TextInputMethodQualifier)mQualifiers[INDEX_TEXT_INPUT_METHOD]; } - + public void setNavigationMethodQualifier(NavigationMethodQualifier qualifier) { mQualifiers[INDEX_NAVIGATION_METHOD] = qualifier; } @@ -213,7 +217,7 @@ public final class FolderConfiguration implements Comparable<FolderConfiguration public NavigationMethodQualifier getNavigationMethodQualifier() { return (NavigationMethodQualifier)mQualifiers[INDEX_NAVIGATION_METHOD]; } - + public void setScreenDimensionQualifier(ScreenDimensionQualifier qualifier) { mQualifiers[INDEX_SCREEN_DIMENSION] = qualifier; } @@ -230,7 +234,7 @@ public final class FolderConfiguration implements Comparable<FolderConfiguration if (obj == this) { return true; } - + if (obj instanceof FolderConfiguration) { FolderConfiguration fc = (FolderConfiguration)obj; for (int i = 0 ; i < INDEX_COUNT ; i++) { @@ -247,7 +251,7 @@ public final class FolderConfiguration implements Comparable<FolderConfiguration return true; } - + return false; } @@ -255,7 +259,7 @@ public final class FolderConfiguration implements Comparable<FolderConfiguration public int hashCode() { return toString().hashCode(); } - + /** * Returns whether the Configuration has only default values. */ @@ -265,52 +269,49 @@ public final class FolderConfiguration implements Comparable<FolderConfiguration return false; } } - + return true; } - + /** * Returns the name of a folder with the configuration. */ - public String getFolderName(ResourceFolderType folder) { + public String getFolderName(ResourceFolderType folder, IAndroidTarget target) { StringBuilder result = new StringBuilder(folder.getName()); - + for (ResourceQualifier qualifier : mQualifiers) { if (qualifier != null) { result.append(QUALIFIER_SEP); - result.append(qualifier.toString()); + result.append(qualifier.getFolderSegment(target)); } } - + return result.toString(); } - + /** - * Returns a string valid for usage in a folder name, or <code>null</code> if the configuration - * is default. + * Returns the name of a folder with the configuration. */ - @Override - public String toString() { - StringBuilder result = null; - - for (ResourceQualifier irq : mQualifiers) { - if (irq != null) { - if (result == null) { - result = new StringBuilder(); - } else { - result.append(QUALIFIER_SEP); - } - result.append(irq.toString()); + public String getFolderName(ResourceFolderType folder, IProject project) { + IAndroidTarget target = null; + if (project != null) { + Sdk currentSdk = Sdk.getCurrent(); + if (currentSdk != null) { + target = currentSdk.getTarget(project); } } - - if (result != null) { - return result.toString(); - } else { - return null; - } + + return getFolderName(folder, target); + } + + /** + * Returns {@link #toDisplayString()}. + */ + @Override + public String toString() { + return toDisplayString(); } - + /** * Returns a string valid for display purpose. */ @@ -322,7 +323,7 @@ public final class FolderConfiguration implements Comparable<FolderConfiguration StringBuilder result = null; int index = 0; ResourceQualifier qualifier = null; - + // pre- language/region qualifiers while (index < INDEX_LANGUAGE) { qualifier = mQualifiers[index++]; @@ -333,10 +334,10 @@ public final class FolderConfiguration implements Comparable<FolderConfiguration result.append(", "); //$NON-NLS-1$ } result.append(qualifier.getStringValue()); - + } } - + // process the language/region qualifier in a custom way, if there are both non null. if (mQualifiers[INDEX_LANGUAGE] != null && mQualifiers[INDEX_REGION] != null) { String language = mQualifiers[INDEX_LANGUAGE].getStringValue(); @@ -348,10 +349,10 @@ public final class FolderConfiguration implements Comparable<FolderConfiguration result.append(", "); //$NON-NLS-1$ } result.append(String.format("%s_%s", language, region)); //$NON-NLS-1$ - + index += 2; } - + // post language/region qualifiers. while (index < INDEX_COUNT) { qualifier = mQualifiers[index++]; @@ -362,7 +363,7 @@ public final class FolderConfiguration implements Comparable<FolderConfiguration result.append(", "); //$NON-NLS-1$ } result.append(qualifier.getStringValue()); - + } } @@ -377,12 +378,12 @@ public final class FolderConfiguration implements Comparable<FolderConfiguration } return -1; } - + // now we compare the qualifiers for (int i = 0 ; i < INDEX_COUNT; i++) { ResourceQualifier qualifier1 = mQualifiers[i]; ResourceQualifier qualifier2 = folderConfig.mQualifiers[i]; - + if (qualifier1 == null) { if (qualifier2 == null) { continue; @@ -394,16 +395,16 @@ public final class FolderConfiguration implements Comparable<FolderConfiguration return 1; } else { int result = qualifier1.compareTo(qualifier2); - + if (result == 0) { continue; } - + return result; } } } - + // if we arrive here, all the qualifier matches return 0; } @@ -421,11 +422,11 @@ public final class FolderConfiguration implements Comparable<FolderConfiguration */ public int match(FolderConfiguration referenceConfig) { int matchCount = 0; - + for (int i = 0 ; i < INDEX_COUNT ; i++) { ResourceQualifier testQualifier = mQualifiers[i]; ResourceQualifier referenceQualifier = referenceConfig.mQualifiers[i]; - + // we only care if testQualifier is non null. If it's null, it's a match but // without increasing the matchCount. if (testQualifier != null) { @@ -434,7 +435,7 @@ public final class FolderConfiguration implements Comparable<FolderConfiguration } else if (testQualifier.equals(referenceQualifier) == false) { return -1; } - + // the qualifier match, increment the count matchCount++; } @@ -454,10 +455,10 @@ public final class FolderConfiguration implements Comparable<FolderConfiguration return i; } } - + return -1; } - + /** * Create default qualifiers. */ @@ -485,7 +486,7 @@ public final class FolderConfiguration implements Comparable<FolderConfiguration count++; } } - + ResourceQualifier[] array = new ResourceQualifier[count]; int index = 0; for (int i = 0 ; i < INDEX_COUNT ; i++) { @@ -493,7 +494,7 @@ public final class FolderConfiguration implements Comparable<FolderConfiguration array[index++] = mQualifiers[i]; } } - + return array; } } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/KeyboardStateQualifier.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/KeyboardStateQualifier.java index 2acebcc..1aa9286 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/KeyboardStateQualifier.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/KeyboardStateQualifier.java @@ -17,6 +17,7 @@ package com.android.ide.eclipse.adt.internal.resources.configurations; import com.android.ide.eclipse.adt.internal.editors.IconFactory; +import com.android.sdklib.IAndroidTarget; import org.eclipse.swt.graphics.Image; @@ -26,7 +27,7 @@ import org.eclipse.swt.graphics.Image; * Resource Qualifier for keyboard state. */ public final class KeyboardStateQualifier extends ResourceQualifier { - + public static final String NAME = "Keyboard State"; private KeyboardState mValue = null; @@ -37,15 +38,15 @@ public final class KeyboardStateQualifier extends ResourceQualifier { public static enum KeyboardState { EXPOSED("keysexposed", "Exposed"), //$NON-NLS-1$ HIDDEN("keyshidden", "Hidden"); //$NON-NLS-1$ - + private String mValue; private String mDisplayValue; - + private KeyboardState(String value, String displayValue) { mValue = value; mDisplayValue = displayValue; } - + /** * Returns the enum for matching the provided qualifier value. * @param value The qualifier value. @@ -57,25 +58,25 @@ public final class KeyboardStateQualifier extends ResourceQualifier { return orient; } } - + return null; } public String getValue() { return mValue; } - + public String getDisplayValue() { return mDisplayValue; } - + public static int getIndex(KeyboardState value) { int i = 0; for (KeyboardState input : values()) { if (value == input) { return i; } - + i++; } @@ -105,27 +106,27 @@ public final class KeyboardStateQualifier extends ResourceQualifier { public KeyboardState getValue() { return mValue; } - + @Override public String getName() { return NAME; } - + @Override public String getShortName() { return "Keyboard"; } - + @Override public Image getIcon() { return IconFactory.getInstance().getIcon("keyboard"); //$NON-NLS-1$ } - + @Override public boolean isValid() { return mValue != null; } - + @Override public boolean checkAndSet(String value, FolderConfiguration config) { KeyboardState orientation = KeyboardState.getEnum(value); @@ -135,10 +136,10 @@ public final class KeyboardStateQualifier extends ResourceQualifier { config.setKeyboardStateQualifier(qualifier); return true; } - + return false; } - + @Override public boolean equals(Object qualifier) { if (qualifier instanceof KeyboardStateQualifier) { @@ -153,19 +154,19 @@ public final class KeyboardStateQualifier extends ResourceQualifier { if (mValue != null) { return mValue.hashCode(); } - + return 0; } - + /** * Returns the string used to represent this qualifier in the folder name. */ @Override - public String toString() { + public String getFolderSegment(IAndroidTarget target) { if (mValue != null) { return mValue.getValue(); } - + return ""; //$NON-NLS-1$ } @@ -174,7 +175,7 @@ public final class KeyboardStateQualifier extends ResourceQualifier { if (mValue != null) { return mValue.getDisplayValue(); } - + return ""; //$NON-NLS-1$ } } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/LanguageQualifier.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/LanguageQualifier.java index 799fc06..a098e44 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/LanguageQualifier.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/LanguageQualifier.java @@ -17,6 +17,7 @@ package com.android.ide.eclipse.adt.internal.resources.configurations; import com.android.ide.eclipse.adt.internal.editors.IconFactory; +import com.android.sdklib.IAndroidTarget; import org.eclipse.swt.graphics.Image; @@ -29,9 +30,9 @@ public final class LanguageQualifier extends ResourceQualifier { private final static Pattern sLanguagePattern = Pattern.compile("^[a-z]{2}$"); //$NON-NLS-1$ public static final String NAME = "Language"; - + private String mValue; - + /** * Creates and returns a qualifier from the given folder segment. If the segment is incorrect, * <code>null</code> is returned. @@ -42,12 +43,12 @@ public final class LanguageQualifier extends ResourceQualifier { if (sLanguagePattern.matcher(segment).matches()) { LanguageQualifier qualifier = new LanguageQualifier(); qualifier.mValue = segment; - + return qualifier; } return null; } - + /** * Returns the folder name segment for the given value. This is equivalent to calling * {@link #toString()} on a {@link LanguageQualifier} object. @@ -58,7 +59,7 @@ public final class LanguageQualifier extends ResourceQualifier { if (sLanguagePattern.matcher(segment).matches()) { return segment; } - + return null; } @@ -66,25 +67,25 @@ public final class LanguageQualifier extends ResourceQualifier { if (mValue != null) { return mValue; } - + return ""; //$NON-NLS-1$ } - + @Override public String getName() { return NAME; } - + @Override public String getShortName() { return NAME; } - + @Override public Image getIcon() { return IconFactory.getInstance().getIcon("language"); //$NON-NLS-1$ } - + @Override public boolean isValid() { return mValue != null; @@ -97,10 +98,10 @@ public final class LanguageQualifier extends ResourceQualifier { config.setLanguageQualifier(qualifier); return true; } - + return false; } - + @Override public boolean equals(Object qualifier) { if (qualifier instanceof LanguageQualifier) { @@ -109,7 +110,7 @@ public final class LanguageQualifier extends ResourceQualifier { } return mValue.equals(((LanguageQualifier)qualifier).mValue); } - + return false; } @@ -118,15 +119,15 @@ public final class LanguageQualifier extends ResourceQualifier { if (mValue != null) { return mValue.hashCode(); } - + return 0; } - + /** * Returns the string used to represent this qualifier in the folder name. */ @Override - public String toString() { + public String getFolderSegment(IAndroidTarget target) { if (mValue != null) { return getFolderSegment(mValue); } @@ -139,7 +140,7 @@ public final class LanguageQualifier extends ResourceQualifier { if (mValue != null) { return mValue; } - + return ""; //$NON-NLS-1$ } } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/NavigationMethodQualifier.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/NavigationMethodQualifier.java index 6315014..0a5c968 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/NavigationMethodQualifier.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/NavigationMethodQualifier.java @@ -17,6 +17,7 @@ package com.android.ide.eclipse.adt.internal.resources.configurations; import com.android.ide.eclipse.adt.internal.editors.IconFactory; +import com.android.sdklib.IAndroidTarget; import org.eclipse.swt.graphics.Image; @@ -26,7 +27,7 @@ import org.eclipse.swt.graphics.Image; * Resource Qualifier for Navigation Method. */ public final class NavigationMethodQualifier extends ResourceQualifier { - + public static final String NAME = "Navigation Method"; private NavigationMethod mValue; @@ -39,15 +40,15 @@ public final class NavigationMethodQualifier extends ResourceQualifier { TRACKBALL("trackball", "Trackball"), //$NON-NLS-1$ WHEEL("wheel", "Wheel"), //$NON-NLS-1$ NONAV("nonav", "No Navigation"); //$NON-NLS-1$ - + private String mValue; private String mDisplay; - + private NavigationMethod(String value, String display) { mValue = value; mDisplay = display; } - + /** * Returns the enum for matching the provided qualifier value. * @param value The qualifier value. @@ -59,14 +60,14 @@ public final class NavigationMethodQualifier extends ResourceQualifier { return orient; } } - + return null; } - + public String getValue() { return mValue; } - + public String getDisplayValue() { return mDisplay; } @@ -77,7 +78,7 @@ public final class NavigationMethodQualifier extends ResourceQualifier { if (nav == value) { return i; } - + i++; } @@ -95,7 +96,7 @@ public final class NavigationMethodQualifier extends ResourceQualifier { return null; } } - + public NavigationMethodQualifier() { // pass } @@ -107,18 +108,18 @@ public final class NavigationMethodQualifier extends ResourceQualifier { public NavigationMethod getValue() { return mValue; } - + @Override public String getName() { return NAME; } - + @Override public String getShortName() { return "Navigation"; } - + @Override public Image getIcon() { return IconFactory.getInstance().getIcon("navpad"); //$NON-NLS-1$ @@ -138,16 +139,16 @@ public final class NavigationMethodQualifier extends ResourceQualifier { config.setNavigationMethodQualifier(qualifier); return true; } - + return false; } - + @Override public boolean equals(Object qualifier) { if (qualifier instanceof NavigationMethodQualifier) { return mValue == ((NavigationMethodQualifier)qualifier).mValue; } - + return false; } @@ -156,19 +157,19 @@ public final class NavigationMethodQualifier extends ResourceQualifier { if (mValue != null) { return mValue.hashCode(); } - + return 0; } - + /** * Returns the string used to represent this qualifier in the folder name. */ @Override - public String toString() { + public String getFolderSegment(IAndroidTarget target) { if (mValue != null) { return mValue.getValue(); } - + return ""; //$NON-NLS-1$ } @@ -177,7 +178,7 @@ public final class NavigationMethodQualifier extends ResourceQualifier { if (mValue != null) { return mValue.getDisplayValue(); } - + return ""; //$NON-NLS-1$ } } 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 c7f7fad..32bd667 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 @@ -17,6 +17,7 @@ package com.android.ide.eclipse.adt.internal.resources.configurations; import com.android.ide.eclipse.adt.internal.editors.IconFactory; +import com.android.sdklib.IAndroidTarget; import org.eclipse.swt.graphics.Image; @@ -33,9 +34,9 @@ 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; - + public final static String NAME = "Mobile Network Code"; - + /** * Creates and returns a qualifier from the given folder segment. If the segment is incorrect, * <code>null</code> is returned. @@ -54,7 +55,7 @@ public final class NetworkCodeQualifier extends ResourceQualifier { // looks like the string we extracted wasn't a valid number. return null; } - + NetworkCodeQualifier qualifier = new NetworkCodeQualifier(); qualifier.mCode = code; return qualifier; @@ -72,29 +73,29 @@ public final class NetworkCodeQualifier extends ResourceQualifier { if (code != DEFAULT_CODE && code >= 1 && code <= 999) { // code is 1-3 digit. return String.format("mnc%1$d", code); //$NON-NLS-1$ } - + return ""; //$NON-NLS-1$ } public int getCode() { return mCode; } - + @Override public String getName() { return NAME; } - + @Override public String getShortName() { return "Network Code"; } - + @Override public Image getIcon() { return IconFactory.getInstance().getIcon("mnc"); //$NON-NLS-1$ } - + @Override public boolean isValid() { return mCode != DEFAULT_CODE; @@ -113,22 +114,22 @@ public final class NetworkCodeQualifier extends ResourceQualifier { // looks like the string we extracted wasn't a valid number. return false; } - + NetworkCodeQualifier qualifier = new NetworkCodeQualifier(); qualifier.mCode = code; config.setNetworkCodeQualifier(qualifier); return true; } - + return false; } - + @Override public boolean equals(Object qualifier) { if (qualifier instanceof NetworkCodeQualifier) { return mCode == ((NetworkCodeQualifier)qualifier).mCode; } - + return false; } @@ -136,12 +137,12 @@ public final class NetworkCodeQualifier extends ResourceQualifier { public int hashCode() { return mCode; } - + /** * Returns the string used to represent this qualifier in the folder name. */ @Override - public String toString() { + public String getFolderSegment(IAndroidTarget target) { return getFolderSegment(mCode); } @@ -150,7 +151,7 @@ public final class NetworkCodeQualifier extends ResourceQualifier { if (mCode != DEFAULT_CODE) { return String.format("MNC %1$d", mCode); } - + return ""; //$NON-NLS-1$ } } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/PixelDensityQualifier.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/PixelDensityQualifier.java index a2c690b..f75e9cb 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/PixelDensityQualifier.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/PixelDensityQualifier.java @@ -17,6 +17,8 @@ package com.android.ide.eclipse.adt.internal.resources.configurations; import com.android.ide.eclipse.adt.internal.editors.IconFactory; +import com.android.sdklib.AndroidVersion; +import com.android.sdklib.IAndroidTarget; import org.eclipse.swt.graphics.Image; @@ -27,118 +29,202 @@ import java.util.regex.Pattern; * Resource Qualifier for Screen Pixel Density. */ public final class PixelDensityQualifier extends ResourceQualifier { - /** Default pixel density value. This means the property is not set. */ - private final static int DEFAULT_DENSITY = -1; - - private final static Pattern sPixelDensityPattern = Pattern.compile("^(\\d+)dpi$");//$NON-NLS-1$ + private final static Pattern sDensityLegacyPattern = Pattern.compile("^(\\d+)dpi$");//$NON-NLS-1$ public static final String NAME = "Pixel Density"; - private int mValue = DEFAULT_DENSITY; - + private Density mValue = Density.MEDIUM; + /** - * Creates and returns a qualifier from the given folder segment. If the segment is incorrect, - * <code>null</code> is returned. - * @param folderSegment the folder segment from which to create a qualifier. - * @return a new {@link CountryCodeQualifier} object or <code>null</code> + * Screen Orientation enum. */ - public static PixelDensityQualifier getQualifier(String folderSegment) { - Matcher m = sPixelDensityPattern.matcher(folderSegment); - if (m.matches()) { - String v = m.group(1); - - int density = -1; - try { - density = Integer.parseInt(v); - } catch (NumberFormatException e) { - // looks like the string we extracted wasn't a valid number. - return null; + public static enum Density { + HIGH("hdpi", 240, "High Density"), //$NON-NLS-1$ + MEDIUM("mdpi", 160, "Medium Density"), //$NON-NLS-1$ + LOW("ldpi", 120, "Low Density"), //$NON-NLS-1$ + NODPI("nodpi", -1, "No Density"); //$NON-NLS-1$ + + private final String mValue; + private final String mDisplayValue; + private final int mDpiValue; + + private Density(String value, int dpiValue, String displayValue) { + mValue = value; + mDpiValue = dpiValue; + mDisplayValue = displayValue; + } + + /** + * Returns the enum for matching the provided qualifier value. + * @param value The qualifier value. + * @return the enum for the qualifier value or null if no matching was found. + */ + static Density getEnum(String value) { + for (Density orient : values()) { + if (orient.mValue.equals(value)) { + return orient; + } } - - PixelDensityQualifier qualifier = new PixelDensityQualifier(); - qualifier.mValue = density; - - return qualifier; + + return null; } - return null; - } - /** - * Returns the folder name segment for the given value. This is equivalent to calling - * {@link #toString()} on a {@link NetworkCodeQualifier} object. - * @param value the value of the qualifier, as returned by {@link #getValue()}. - */ - public static String getFolderSegment(int value) { - if (value != DEFAULT_DENSITY) { - return String.format("%1$ddpi", value); //$NON-NLS-1$ + static Density getLegacyEnum(String value) { + Matcher m = sDensityLegacyPattern.matcher(value); + if (m.matches()) { + String v = m.group(1); + + try { + int density = Integer.parseInt(v); + for (Density orient : values()) { + if (orient.mDpiValue == density) { + return orient; + } + } + } catch (NumberFormatException e) { + // looks like the string we extracted wasn't a valid number + // which really shouldn't happen since the regexp would have failed. + } + } + return null; } - - return ""; //$NON-NLS-1$ + + public String getValue() { + return mValue; + } + + public int getDpiValue() { + return mDpiValue; + } + + public String getLegacyValue() { + if (this != NODPI) { + return String.format("%1$ddpi", mDpiValue); + } + + return ""; + } + + public String getDisplayValue() { + return mDisplayValue; + } + + public static int getIndex(Density value) { + int i = 0; + for (Density input : values()) { + if (value == input) { + return i; + } + + i++; + } + + return -1; + } + + public static Density getByIndex(int index) { + int i = 0; + for (Density value : values()) { + if (i == index) { + return value; + } + i++; + } + return null; + } + } + + public PixelDensityQualifier() { + // pass + } + + public PixelDensityQualifier(Density value) { + mValue = value; } - public int getValue() { + public Density getValue() { return mValue; } - + @Override public String getName() { return NAME; } - + @Override public String getShortName() { return NAME; } - + @Override public Image getIcon() { return IconFactory.getInstance().getIcon("dpi"); //$NON-NLS-1$ } - + @Override public boolean isValid() { - return mValue != DEFAULT_DENSITY; + return mValue != null; } @Override public boolean checkAndSet(String value, FolderConfiguration config) { - PixelDensityQualifier qualifier = getQualifier(value); - if (qualifier != null) { + Density density = Density.getEnum(value); + if (density == null) { + density = Density.getLegacyEnum(value); + } + + if (density != null) { + PixelDensityQualifier qualifier = new PixelDensityQualifier(); + qualifier.mValue = density; config.setPixelDensityQualifier(qualifier); return true; } - + return false; } - + @Override public boolean equals(Object qualifier) { if (qualifier instanceof PixelDensityQualifier) { return mValue == ((PixelDensityQualifier)qualifier).mValue; } - + return false; } @Override public int hashCode() { - return mValue; + if (mValue != null) { + return mValue.hashCode(); + } + + return 0; } - + /** * Returns the string used to represent this qualifier in the folder name. */ @Override - public String toString() { - return getFolderSegment(mValue); + public String getFolderSegment(IAndroidTarget target) { + if (mValue != null) { + if (target != null) { + AndroidVersion version = target.getVersion(); + if (version.getApiLevel() <= 3 && version.getCodename() == null) { + return mValue.getLegacyValue(); + } + } + return mValue.getValue(); + } + + return ""; //$NON-NLS-1$ } @Override public String getStringValue() { - if (mValue != DEFAULT_DENSITY) { - return String.format("%1$d dpi", mValue); + if (mValue != null) { + return mValue.getDisplayValue(); } - + return ""; //$NON-NLS-1$ } } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/RegionQualifier.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/RegionQualifier.java index be54f2b..3f3abcc 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/RegionQualifier.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/RegionQualifier.java @@ -17,6 +17,7 @@ package com.android.ide.eclipse.adt.internal.resources.configurations; import com.android.ide.eclipse.adt.internal.editors.IconFactory; +import com.android.sdklib.IAndroidTarget; import org.eclipse.swt.graphics.Image; @@ -30,9 +31,9 @@ public final class RegionQualifier extends ResourceQualifier { private final static Pattern sRegionPattern = Pattern.compile("^r([A-Z]{2})$"); //$NON-NLS-1$ public static final String NAME = "Region"; - + private String mValue; - + /** * Creates and returns a qualifier from the given folder segment. If the segment is incorrect, * <code>null</code> is returned. @@ -49,7 +50,7 @@ public final class RegionQualifier extends ResourceQualifier { } return null; } - + /** * Returns the folder name segment for the given value. This is equivalent to calling * {@link #toString()} on a {@link RegionQualifier} object. @@ -62,7 +63,7 @@ public final class RegionQualifier extends ResourceQualifier { return segment; } } - + return ""; //$NON-NLS-1$ } @@ -70,20 +71,20 @@ public final class RegionQualifier extends ResourceQualifier { if (mValue != null) { return mValue; } - + return ""; //$NON-NLS-1$ } - + @Override public String getName() { return NAME; } - + @Override public String getShortName() { return NAME; } - + @Override public Image getIcon() { return IconFactory.getInstance().getIcon("region"); //$NON-NLS-1$ @@ -101,10 +102,10 @@ public final class RegionQualifier extends ResourceQualifier { config.setRegionQualifier(qualifier); return true; } - + return false; } - + @Override public boolean equals(Object qualifier) { if (qualifier instanceof RegionQualifier) { @@ -113,7 +114,7 @@ public final class RegionQualifier extends ResourceQualifier { } return mValue.equals(((RegionQualifier)qualifier).mValue); } - + return false; } @@ -122,15 +123,15 @@ public final class RegionQualifier extends ResourceQualifier { if (mValue != null) { return mValue.hashCode(); } - + return 0; } - + /** * Returns the string used to represent this qualifier in the folder name. */ @Override - public String toString() { + public String getFolderSegment(IAndroidTarget target) { return getFolderSegment(mValue); } @@ -139,7 +140,7 @@ public final class RegionQualifier extends ResourceQualifier { if (mValue != null) { return mValue; } - + return ""; //$NON-NLS-1$ } } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/ResourceQualifier.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/ResourceQualifier.java index b644e8f..bfee8d2 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/ResourceQualifier.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/ResourceQualifier.java @@ -16,6 +16,8 @@ package com.android.ide.eclipse.adt.internal.resources.configurations; +import com.android.sdklib.IAndroidTarget; + import org.eclipse.swt.graphics.Image; /** @@ -23,28 +25,28 @@ import org.eclipse.swt.graphics.Image; * <p/>The resource qualifier classes are designed as immutable. */ public abstract class ResourceQualifier implements Comparable<ResourceQualifier> { - + /** * Returns the human readable name of the qualifier. */ public abstract String getName(); - + /** * Returns a shorter human readable name for the qualifier. * @see #getName() */ public abstract String getShortName(); - + /** * Returns the icon for the qualifier. */ public abstract Image getIcon(); - + /** * Returns whether the qualifier has a valid filter value. */ public abstract boolean isValid(); - + /** * Check if the value is valid for this qualifier, and if so sets the value * into a Folder Configuration. @@ -53,13 +55,17 @@ public abstract class ResourceQualifier implements Comparable<ResourceQualifier> * @return true if the value was valid and was set. */ public abstract boolean checkAndSet(String value, FolderConfiguration config); - + /** * Returns a string formated to be used in a folder name. * <p/>This is declared as abstract to force children classes to implement it. */ + public abstract String getFolderSegment(IAndroidTarget target); + @Override - public abstract String toString(); + public String toString() { + return getFolderSegment(null); + } /** * Returns a string formatted for display purpose. @@ -72,7 +78,7 @@ public abstract class ResourceQualifier implements Comparable<ResourceQualifier> */ @Override public abstract boolean equals(Object object); - + /** * Returns a hash code value for the object. * <p/>This is declared as abstract to force children classes to implement it. diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/ScreenDimensionQualifier.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/ScreenDimensionQualifier.java index e756644..ff8a930 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/ScreenDimensionQualifier.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/ScreenDimensionQualifier.java @@ -17,6 +17,7 @@ package com.android.ide.eclipse.adt.internal.resources.configurations; import com.android.ide.eclipse.adt.internal.editors.IconFactory; +import com.android.sdklib.IAndroidTarget; import org.eclipse.swt.graphics.Image; @@ -46,7 +47,7 @@ public final class ScreenDimensionQualifier extends ResourceQualifier { * 200 but that'll be Y in landscape and X in portrait. * Default value is <code>DEFAULT_SIZE</code> */ private int mValue2 = DEFAULT_SIZE; - + public int getValue1() { return mValue1; } @@ -54,17 +55,17 @@ public final class ScreenDimensionQualifier extends ResourceQualifier { public int getValue2() { return mValue2; } - + @Override public String getName() { return NAME; } - + @Override public String getShortName() { return "Dimension"; } - + @Override public Image getIcon() { return IconFactory.getInstance().getIcon("dimension"); //$NON-NLS-1$ @@ -81,7 +82,7 @@ public final class ScreenDimensionQualifier extends ResourceQualifier { if (m.matches()) { String d1 = m.group(1); String d2 = m.group(2); - + ScreenDimensionQualifier qualifier = getQualifier(d1, d2); if (qualifier != null) { config.setScreenDimensionQualifier(qualifier); @@ -90,14 +91,14 @@ public final class ScreenDimensionQualifier extends ResourceQualifier { } return false; } - + @Override public boolean equals(Object qualifier) { if (qualifier instanceof ScreenDimensionQualifier) { ScreenDimensionQualifier q = (ScreenDimensionQualifier)qualifier; return (mValue1 == q.mValue1 && mValue2 == q.mValue2); } - + return false; } @@ -105,12 +106,12 @@ public final class ScreenDimensionQualifier extends ResourceQualifier { public int hashCode() { return toString().hashCode(); } - + public static ScreenDimensionQualifier getQualifier(String size1, String size2) { try { int s1 = Integer.parseInt(size1); int s2 = Integer.parseInt(size2); - + ScreenDimensionQualifier qualifier = new ScreenDimensionQualifier(); if (s1 > s2) { @@ -125,7 +126,7 @@ public final class ScreenDimensionQualifier extends ResourceQualifier { } catch (NumberFormatException e) { // looks like the string we extracted wasn't a valid number. } - + return null; } @@ -133,7 +134,7 @@ public final class ScreenDimensionQualifier extends ResourceQualifier { * Returns the string used to represent this qualifier in the folder name. */ @Override - public String toString() { + public String getFolderSegment(IAndroidTarget target) { return String.format("%1$dx%2$d", mValue1, mValue2); //$NON-NLS-1$ } @@ -142,7 +143,7 @@ public final class ScreenDimensionQualifier extends ResourceQualifier { if (mValue1 != -1 && mValue2 != -1) { return String.format("%1$dx%2$d", mValue1, mValue2); } - + return ""; //$NON-NLS-1$ } } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/ScreenOrientationQualifier.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/ScreenOrientationQualifier.java index 6e1b829..85d0c03 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/ScreenOrientationQualifier.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/ScreenOrientationQualifier.java @@ -17,6 +17,7 @@ package com.android.ide.eclipse.adt.internal.resources.configurations; import com.android.ide.eclipse.adt.internal.editors.IconFactory; +import com.android.sdklib.IAndroidTarget; import org.eclipse.swt.graphics.Image; @@ -24,7 +25,7 @@ import org.eclipse.swt.graphics.Image; * Resource Qualifier for Screen Orientation. */ public final class ScreenOrientationQualifier extends ResourceQualifier { - + public static final String NAME = "Screen Orientation"; private ScreenOrientation mValue = null; @@ -36,15 +37,15 @@ public final class ScreenOrientationQualifier extends ResourceQualifier { PORTRAIT("port", "Portrait"), //$NON-NLS-1$ LANDSCAPE("land", "Landscape"), //$NON-NLS-1$ SQUARE("square", "Square"); //$NON-NLS-1$ - + private String mValue; private String mDisplayValue; - + private ScreenOrientation(String value, String displayValue) { mValue = value; mDisplayValue = displayValue; } - + /** * Returns the enum for matching the provided qualifier value. * @param value The qualifier value. @@ -63,18 +64,18 @@ public final class ScreenOrientationQualifier extends ResourceQualifier { public String getValue() { return mValue; } - + public String getDisplayValue() { return mDisplayValue; } - + public static int getIndex(ScreenOrientation orientation) { int i = 0; for (ScreenOrientation orient : values()) { if (orient == orientation) { return i; } - + i++; } @@ -104,22 +105,22 @@ public final class ScreenOrientationQualifier extends ResourceQualifier { public ScreenOrientation getValue() { return mValue; } - + @Override public String getName() { return NAME; } - + @Override public String getShortName() { return "Orientation"; } - + @Override public Image getIcon() { return IconFactory.getInstance().getIcon("orientation"); //$NON-NLS-1$ } - + @Override public boolean isValid() { return mValue != null; @@ -133,10 +134,10 @@ public final class ScreenOrientationQualifier extends ResourceQualifier { config.setScreenOrientationQualifier(qualifier); return true; } - + return false; } - + @Override public boolean equals(Object qualifier) { if (qualifier instanceof ScreenOrientationQualifier) { @@ -151,19 +152,19 @@ public final class ScreenOrientationQualifier extends ResourceQualifier { if (mValue != null) { return mValue.hashCode(); } - + return 0; } - + /** * Returns the string used to represent this qualifier in the folder name. */ @Override - public String toString() { + public String getFolderSegment(IAndroidTarget target) { if (mValue != null) { return mValue.getValue(); } - + return ""; //$NON-NLS-1$ } @@ -172,7 +173,7 @@ public final class ScreenOrientationQualifier extends ResourceQualifier { if (mValue != null) { return mValue.getDisplayValue(); } - + return ""; //$NON-NLS-1$ } } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/TextInputMethodQualifier.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/TextInputMethodQualifier.java index add45cc..6289147 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/TextInputMethodQualifier.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/TextInputMethodQualifier.java @@ -17,6 +17,7 @@ package com.android.ide.eclipse.adt.internal.resources.configurations; import com.android.ide.eclipse.adt.internal.editors.IconFactory; +import com.android.sdklib.IAndroidTarget; import org.eclipse.swt.graphics.Image; @@ -31,7 +32,7 @@ public final class TextInputMethodQualifier extends ResourceQualifier { public static final String NAME = "Text Input Method"; private TextInputMethod mValue; - + /** * Screen Orientation enum. */ @@ -39,15 +40,15 @@ public final class TextInputMethodQualifier extends ResourceQualifier { NOKEY("nokeys", "No Keys"), //$NON-NLS-1$ QWERTY("qwerty", "Qwerty"), //$NON-NLS-1$ TWELVEKEYS("12key", "12 Key"); //$NON-NLS-1$ - + private String mValue; private String mDisplayValue; - + private TextInputMethod(String value, String displayValue) { mValue = value; mDisplayValue = displayValue; } - + /** * Returns the enum for matching the provided qualifier value. * @param value The qualifier value. @@ -59,14 +60,14 @@ public final class TextInputMethodQualifier extends ResourceQualifier { return orient; } } - + return null; } public String getValue() { return mValue; } - + public String getDisplayValue() { return mDisplayValue; } @@ -77,7 +78,7 @@ public final class TextInputMethodQualifier extends ResourceQualifier { if (value == input) { return i; } - + i++; } @@ -95,7 +96,7 @@ public final class TextInputMethodQualifier extends ResourceQualifier { return null; } } - + public TextInputMethodQualifier() { // pass } @@ -107,17 +108,17 @@ public final class TextInputMethodQualifier extends ResourceQualifier { public TextInputMethod getValue() { return mValue; } - + @Override public String getName() { return NAME; } - + @Override public String getShortName() { return "Text Input"; } - + @Override public Image getIcon() { return IconFactory.getInstance().getIcon("text_input"); //$NON-NLS-1$ @@ -137,10 +138,10 @@ public final class TextInputMethodQualifier extends ResourceQualifier { config.setTextInputMethodQualifier(qualifier); return true; } - + return false; } - + @Override public boolean equals(Object qualifier) { if (qualifier instanceof TextInputMethodQualifier) { @@ -155,7 +156,7 @@ public final class TextInputMethodQualifier extends ResourceQualifier { if (mValue != null) { return mValue.hashCode(); } - + return 0; } @@ -163,11 +164,11 @@ public final class TextInputMethodQualifier extends ResourceQualifier { * Returns the string used to represent this qualifier in the folder name. */ @Override - public String toString() { + public String getFolderSegment(IAndroidTarget target) { if (mValue != null) { return mValue.getValue(); } - + return ""; //$NON-NLS-1$ } @@ -176,7 +177,7 @@ public final class TextInputMethodQualifier extends ResourceQualifier { if (mValue != null) { return mValue.getDisplayValue(); } - + return ""; //$NON-NLS-1$ } } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/TouchScreenQualifier.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/TouchScreenQualifier.java index 1ed7d95..758c87f 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/TouchScreenQualifier.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/TouchScreenQualifier.java @@ -17,6 +17,7 @@ package com.android.ide.eclipse.adt.internal.resources.configurations; import com.android.ide.eclipse.adt.internal.editors.IconFactory; +import com.android.sdklib.IAndroidTarget; import org.eclipse.swt.graphics.Image; @@ -29,7 +30,7 @@ public final class TouchScreenQualifier extends ResourceQualifier { public static final String NAME = "Touch Screen"; private TouchScreenType mValue; - + /** * Screen Orientation enum. */ @@ -37,15 +38,15 @@ public final class TouchScreenQualifier extends ResourceQualifier { NOTOUCH("notouch", "No Touch"), //$NON-NLS-1$ STYLUS("stylus", "Stylus"), //$NON-NLS-1$ FINGER("finger", "Finger"); //$NON-NLS-1$ - + private String mValue; private String mDisplayValue; - + private TouchScreenType(String value, String displayValue) { mValue = value; mDisplayValue = displayValue; } - + /** * Returns the enum for matching the provided qualifier value. * @param value The qualifier value. @@ -57,14 +58,14 @@ public final class TouchScreenQualifier extends ResourceQualifier { return orient; } } - + return null; } public String getValue() { return mValue; } - + public String getDisplayValue() { return mDisplayValue; } @@ -75,7 +76,7 @@ public final class TouchScreenQualifier extends ResourceQualifier { if (t == touch) { return i; } - + i++; } @@ -94,7 +95,7 @@ public final class TouchScreenQualifier extends ResourceQualifier { return null; } } - + public TouchScreenQualifier() { // pass } @@ -106,17 +107,17 @@ public final class TouchScreenQualifier extends ResourceQualifier { public TouchScreenType getValue() { return mValue; } - + @Override public String getName() { return NAME; } - + @Override public String getShortName() { return NAME; } - + @Override public Image getIcon() { return IconFactory.getInstance().getIcon("touch"); //$NON-NLS-1$ @@ -136,10 +137,10 @@ public final class TouchScreenQualifier extends ResourceQualifier { config.setTouchTypeQualifier(qualifier); return true; } - + return false; } - + @Override public boolean equals(Object qualifier) { if (qualifier instanceof TouchScreenQualifier) { @@ -153,7 +154,7 @@ public final class TouchScreenQualifier extends ResourceQualifier { if (mValue != null) { return mValue.hashCode(); } - + return 0; } @@ -161,11 +162,11 @@ public final class TouchScreenQualifier extends ResourceQualifier { * Returns the string used to represent this qualifier in the folder name. */ @Override - public String toString() { + public String getFolderSegment(IAndroidTarget target) { if (mValue != null) { return mValue.getValue(); } - + return ""; //$NON-NLS-1$ } @@ -174,7 +175,7 @@ public final class TouchScreenQualifier extends ResourceQualifier { if (mValue != null) { return mValue.getDisplayValue(); } - + return ""; //$NON-NLS-1$ } } 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 d6cfeae..f2e883d 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 @@ -378,6 +378,20 @@ public class Sdk implements IProjectListener { } /** + * Return the {@link AndroidTargetData} for a given {@link IProject}. + */ + public AndroidTargetData getTargetData(IProject project) { + synchronized (AdtPlugin.getDefault().getSdkLockObject()) { + IAndroidTarget target = getTarget(project); + if (target != null) { + return getTargetData(target); + } + } + + return null; + } + + /** * Returns the configuration map for a given project. * <p/>The Map key are name to be used in the apk filename, while the values are comma separated * config values. The config value can be passed directly to aapt through the -c option. diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/ConfigurationSelector.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/ConfigurationSelector.java index 7378d41..34a2391 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/ConfigurationSelector.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/ConfigurationSelector.java @@ -31,6 +31,7 @@ import com.android.ide.eclipse.adt.internal.resources.configurations.TextInputMe import com.android.ide.eclipse.adt.internal.resources.configurations.TouchScreenQualifier; import com.android.ide.eclipse.adt.internal.resources.configurations.KeyboardStateQualifier.KeyboardState; import com.android.ide.eclipse.adt.internal.resources.configurations.NavigationMethodQualifier.NavigationMethod; +import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier.Density; import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier.ScreenOrientation; import com.android.ide.eclipse.adt.internal.resources.configurations.TextInputMethodQualifier.TextInputMethod; import com.android.ide.eclipse.adt.internal.resources.configurations.TouchScreenQualifier.TouchScreenType; @@ -80,13 +81,13 @@ import java.util.HashMap; * <ul> * <li>Use {@link #setConfiguration(String)} or {@link #setConfiguration(FolderConfiguration)}. * <li>Retrieve the configuration using {@link #getConfiguration(FolderConfiguration)}. - * </ul> + * </ul> */ public class ConfigurationSelector extends Composite { - + public static final int WIDTH_HINT = 600; public static final int HEIGHT_HINT = 250; - + private Runnable mOnChangeListener; private TableViewer mFullTableViewer; @@ -94,16 +95,16 @@ public class ConfigurationSelector extends Composite { private Button mAddButton; private Button mRemoveButton; private StackLayout mStackLayout; - + private boolean mOnRefresh = false; private final FolderConfiguration mBaseConfiguration = new FolderConfiguration(); private final FolderConfiguration mSelectedConfiguration = new FolderConfiguration(); - + private final HashMap<Class<? extends ResourceQualifier>, QualifierEditBase> mUiMap = new HashMap<Class<? extends ResourceQualifier>, QualifierEditBase>(); private Composite mQualifierEditParent; - + /** * Basic of {@link VerifyListener} to only accept digits. */ @@ -119,7 +120,7 @@ public class ConfigurationSelector extends Composite { } } } - + /** * Implementation of {@link VerifyListener} for Country Code qualifiers. */ @@ -138,7 +139,7 @@ public class ConfigurationSelector extends Composite { } } } - + /** * Implementation of {@link VerifyListener} for the Language and Region qualifiers. */ @@ -149,7 +150,7 @@ public class ConfigurationSelector extends Composite { e.doit = false; return; } - + // check for lower case only. for (int i = 0 ; i < e.text.length(); i++) { char letter = e.text.charAt(i); @@ -160,17 +161,17 @@ public class ConfigurationSelector extends Composite { } } } - + /** * Implementation of {@link VerifyListener} for the Pixel Density qualifier. */ public static class DensityVerifier extends DigitVerifier { } - + /** * Implementation of {@link VerifyListener} for the Screen Dimension qualifier. */ public static class DimensionVerifier extends DigitVerifier { } - + /** * Enum for the state of the configuration being created. */ @@ -186,18 +187,18 @@ public class ConfigurationSelector extends Composite { GridLayout gl = new GridLayout(4, false); gl.marginWidth = gl.marginHeight = 0; setLayout(gl); - + // first column is the first table final Table fullTable = new Table(this, SWT.SINGLE | SWT.FULL_SELECTION | SWT.BORDER); fullTable.setLayoutData(new GridData(GridData.FILL_BOTH)); fullTable.setHeaderVisible(true); fullTable.setLinesVisible(true); - + // create the column final TableColumn fullTableColumn = new TableColumn(fullTable, SWT.LEFT); // set the header fullTableColumn.setText("Available Qualifiers"); - + fullTable.addControlListener(new ControlAdapter() { @Override public void controlResized(ControlEvent e) { @@ -217,24 +218,24 @@ public class ConfigurationSelector extends Composite { if (selection instanceof IStructuredSelection) { IStructuredSelection structSelection = (IStructuredSelection)selection; Object first = structSelection.getFirstElement(); - + if (first instanceof ResourceQualifier) { mAddButton.setEnabled(true); return; } } - + mAddButton.setEnabled(false); } }); - + // 2nd column is the left/right arrow button Composite buttonComposite = new Composite(this, SWT.NONE); gl = new GridLayout(1, false); gl.marginWidth = gl.marginHeight = 0; buttonComposite.setLayout(gl); buttonComposite.setLayoutData(new GridData(GridData.FILL_VERTICAL)); - + new Composite(buttonComposite, SWT.NONE); mAddButton = new Button(buttonComposite, SWT.BORDER | SWT.PUSH); mAddButton.setText("->"); @@ -242,20 +243,20 @@ public class ConfigurationSelector extends Composite { mAddButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { - IStructuredSelection selection = + IStructuredSelection selection = (IStructuredSelection)mFullTableViewer.getSelection(); - + Object first = selection.getFirstElement(); if (first instanceof ResourceQualifier) { ResourceQualifier qualifier = (ResourceQualifier)first; - + mBaseConfiguration.removeQualifier(qualifier); mSelectedConfiguration.addQualifier(qualifier); - + mFullTableViewer.refresh(); mSelectionTableViewer.refresh(); mSelectionTableViewer.setSelection(new StructuredSelection(qualifier), true); - + onChange(false /* keepSelection */); } } @@ -267,19 +268,19 @@ public class ConfigurationSelector extends Composite { mRemoveButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { - IStructuredSelection selection = + IStructuredSelection selection = (IStructuredSelection)mSelectionTableViewer.getSelection(); - + Object first = selection.getFirstElement(); if (first instanceof ResourceQualifier) { ResourceQualifier qualifier = (ResourceQualifier)first; - + mSelectedConfiguration.removeQualifier(qualifier); mBaseConfiguration.addQualifier(qualifier); mFullTableViewer.refresh(); mSelectionTableViewer.refresh(); - + onChange(false /* keepSelection */); } } @@ -290,12 +291,12 @@ public class ConfigurationSelector extends Composite { selectionTable.setLayoutData(new GridData(GridData.FILL_BOTH)); selectionTable.setHeaderVisible(true); selectionTable.setLinesVisible(true); - + // create the column final TableColumn selectionTableColumn = new TableColumn(selectionTable, SWT.LEFT); // set the header selectionTableColumn.setText("Chosen Qualifiers"); - + selectionTable.addControlListener(new ControlAdapter() { @Override public void controlResized(ControlEvent e) { @@ -318,22 +319,22 @@ public class ConfigurationSelector extends Composite { ISelection selection = event.getSelection(); if (selection instanceof IStructuredSelection) { IStructuredSelection structSelection = (IStructuredSelection)selection; - + if (structSelection.isEmpty() == false) { Object first = structSelection.getFirstElement(); - + if (first instanceof ResourceQualifier) { mRemoveButton.setEnabled(true); - + QualifierEditBase composite = mUiMap.get(first.getClass()); - + if (composite != null) { composite.setQualifier((ResourceQualifier)first); } - + mStackLayout.topControl = composite; mQualifierEditParent.layout(); - + return; } } else { @@ -341,16 +342,16 @@ public class ConfigurationSelector extends Composite { mQualifierEditParent.layout(); } } - + mRemoveButton.setEnabled(false); } }); - - // 4th column is the detail of the selected qualifier + + // 4th column is the detail of the selected qualifier mQualifierEditParent = new Composite(this, SWT.NONE); mQualifierEditParent.setLayout(mStackLayout = new StackLayout()); mQualifierEditParent.setLayoutData(new GridData(GridData.FILL_VERTICAL)); - + // create the UI for all the qualifiers, and associate them to the ResourceQualifer class. mUiMap.put(CountryCodeQualifier.class, new MCCEdit(mQualifierEditParent)); mUiMap.put(NetworkCodeQualifier.class, new MNCEdit(mQualifierEditParent)); @@ -364,7 +365,7 @@ public class ConfigurationSelector extends Composite { mUiMap.put(NavigationMethodQualifier.class, new NavigationEdit(mQualifierEditParent)); mUiMap.put(ScreenDimensionQualifier.class, new ScreenDimensionEdit(mQualifierEditParent)); } - + /** * Sets a listener to be notified when the configuration changes. * @param listener A {@link Runnable} whose <code>run()</code> method is called when the @@ -373,7 +374,7 @@ public class ConfigurationSelector extends Composite { public void setOnChangeListener(Runnable listener) { mOnChangeListener = listener; } - + /** * Initialize the UI with a given {@link FolderConfiguration}. This must * be called from the UI thread. @@ -382,24 +383,24 @@ public class ConfigurationSelector extends Composite { public void setConfiguration(FolderConfiguration config) { mSelectedConfiguration.set(config); mSelectionTableViewer.refresh(); - + // create the base config, which is the default config minus the qualifiers // in SelectedConfiguration mBaseConfiguration.substract(mSelectedConfiguration); mFullTableViewer.refresh(); } - + /** * Initialize the UI with the configuration represented by a resource folder name. * This must be called from the UI thread. - * + * * @param folderSegments the segments of the folder name, * split using {@link FolderConfiguration#QUALIFIER_SEP}. * @return true if success, or false if the folder name is not a valid name. */ public boolean setConfiguration(String[] folderSegments) { FolderConfiguration config = ResourceManager.getInstance().getConfig(folderSegments); - + if (config == null) { return false; } @@ -408,7 +409,7 @@ public class ConfigurationSelector extends Composite { return true; } - + /** * Initialize the UI with the configuration represented by a resource folder name. * This must be called from the UI thread. @@ -421,7 +422,7 @@ public class ConfigurationSelector extends Composite { return setConfiguration(folderSegments); } - + /** * Gets the configuration as setup by the widget. * @param config the {@link FolderConfiguration} object to be filled with the information @@ -430,7 +431,7 @@ public class ConfigurationSelector extends Composite { public void getConfiguration(FolderConfiguration config) { config.set(mSelectedConfiguration); } - + /** * Returns the state of the configuration being edited/created. */ @@ -438,14 +439,14 @@ public class ConfigurationSelector extends Composite { if (mSelectedConfiguration.getInvalidQualifier() != null) { return ConfigurationState.INVALID_CONFIG; } - + if (mSelectedConfiguration.checkRegion() == false) { return ConfigurationState.REGION_WITHOUT_LANGUAGE; } - + return ConfigurationState.OK; } - + /** * Returns the first invalid qualifier of the configuration being edited/created, * or <code>null<code> if they are all valid (or if none exists). @@ -469,7 +470,7 @@ public class ConfigurationSelector extends Composite { } mSelectionTableViewer.refresh(true); - + if (keepSelection) { mSelectionTableViewer.setSelection(selection); mOnRefresh = false; @@ -479,12 +480,12 @@ public class ConfigurationSelector extends Composite { mOnChangeListener.run(); } } - + /** * Content provider around a {@link FolderConfiguration}. */ private static class QualifierContentProvider implements IStructuredContentProvider { - + private FolderConfiguration mInput; public QualifierContentProvider() { @@ -505,12 +506,12 @@ public class ConfigurationSelector extends Composite { } } } - + /** * Label provider for {@link ResourceQualifier} objects. */ private static class QualifierLabelProvider implements ITableLabelProvider { - + private final boolean mShowQualifierValue; public QualifierLabelProvider(boolean showQualifierValue) { @@ -528,7 +529,7 @@ public class ConfigurationSelector extends Composite { } else { return value; } - + } else { return ((ResourceQualifier)element).getShortName(); } @@ -536,7 +537,7 @@ public class ConfigurationSelector extends Composite { return null; } - + public Image getColumnImage(Object element, int columnIndex) { // only one column, so we can ignore columnIndex if (element instanceof ResourceQualifier) { @@ -563,7 +564,7 @@ public class ConfigurationSelector extends Composite { // pass } } - + /** * Base class for Edit widget for {@link ResourceQualifier}. */ @@ -575,10 +576,10 @@ public class ConfigurationSelector extends Composite { new Label(this, SWT.NONE).setText(title); } - + public abstract void setQualifier(ResourceQualifier qualifier); } - + /** * Edit widget for {@link CountryCodeQualifier}. */ @@ -588,13 +589,13 @@ public class ConfigurationSelector extends Composite { public MCCEdit(Composite parent) { super(parent, CountryCodeQualifier.NAME); - + mText = new Text(this, SWT.BORDER); mText.addVerifyListener(new MobileCodeVerifier()); mText.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { onTextChange(); - } + } }); mText.addFocusListener(new FocusAdapter() { @@ -603,13 +604,13 @@ public class ConfigurationSelector extends Composite { onTextChange(); } }); - + new Label(this, SWT.NONE).setText("(3 digit code)"); } - + private void onTextChange() { String value = mText.getText(); - + if (value.length() == 0) { // empty string, means a qualifier with no value. // Since the qualifier classes are immutable, and we don't want to @@ -632,7 +633,7 @@ public class ConfigurationSelector extends Composite { mSelectedConfiguration.setCountryCodeQualifier(new CountryCodeQualifier()); } } - + // notify of change onChange(true /* keepSelection */); } @@ -640,7 +641,7 @@ public class ConfigurationSelector extends Composite { @Override public void setQualifier(ResourceQualifier qualifier) { CountryCodeQualifier q = (CountryCodeQualifier)qualifier; - + mText.setText(Integer.toString(q.getCode())); } } @@ -653,7 +654,7 @@ public class ConfigurationSelector extends Composite { public MNCEdit(Composite parent) { super(parent, NetworkCodeQualifier.NAME); - + mText = new Text(this, SWT.BORDER); mText.addVerifyListener(new MobileCodeVerifier()); mText.addModifyListener(new ModifyListener() { @@ -670,10 +671,10 @@ public class ConfigurationSelector extends Composite { new Label(this, SWT.NONE).setText("(1-3 digit code)"); } - + private void onTextChange() { String value = mText.getText(); - + if (value.length() == 0) { // empty string, means a qualifier with no value. // Since the qualifier classes are immutable, and we don't want to @@ -696,19 +697,19 @@ public class ConfigurationSelector extends Composite { mSelectedConfiguration.setNetworkCodeQualifier(new NetworkCodeQualifier()); } } - + // notify of change onChange(true /* keepSelection */); - } + } @Override public void setQualifier(ResourceQualifier qualifier) { NetworkCodeQualifier q = (NetworkCodeQualifier)qualifier; - + mText.setText(Integer.toString(q.getCode())); } } - + /** * Edit widget for {@link LanguageQualifier}. */ @@ -741,7 +742,7 @@ public class ConfigurationSelector extends Composite { private void onLanguageChange() { // update the current config String value = mLanguage.getText(); - + if (value.length() == 0) { // empty string, means no qualifier. // Since the qualifier classes are immutable, and we don't want to @@ -809,7 +810,7 @@ public class ConfigurationSelector extends Composite { private void onRegionChange() { // update the current config String value = mRegion.getText(); - + if (value.length() == 0) { // empty string, means no qualifier. // Since the qualifier classes are immutable, and we don't want to @@ -844,7 +845,7 @@ public class ConfigurationSelector extends Composite { } } } - + /** * Edit widget for {@link ScreenOrientationQualifier}. */ @@ -908,63 +909,58 @@ public class ConfigurationSelector extends Composite { * Edit widget for {@link PixelDensityQualifier}. */ private class PixelDensityEdit extends QualifierEditBase { - private Text mText; + private Combo mDensity; public PixelDensityEdit(Composite parent) { super(parent, PixelDensityQualifier.NAME); - - mText = new Text(this, SWT.BORDER); - mText.addVerifyListener(new DensityVerifier()); - mText.addModifyListener(new ModifyListener() { - public void modifyText(ModifyEvent e) { - onTextChange(); + + mDensity = new Combo(this, SWT.DROP_DOWN | SWT.READ_ONLY); + Density[] soValues = Density.values(); + for (Density value : soValues) { + mDensity.add(value.getDisplayValue()); + } + + mDensity.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + mDensity.addSelectionListener(new SelectionListener() { + public void widgetDefaultSelected(SelectionEvent e) { + onDensityChange(); } - }); - mText.addFocusListener(new FocusAdapter() { - @Override - public void focusLost(FocusEvent e) { - onTextChange(); + public void widgetSelected(SelectionEvent e) { + onDensityChange(); } }); + } - - private void onTextChange() { - String value = mText.getText(); - - if (value.length() == 0) { - // empty string, means a qualifier with no value. + + private void onDensityChange() { + // update the current config + int index = mDensity.getSelectionIndex(); + + if (index != -1) { + mSelectedConfiguration.setPixelDensityQualifier(new PixelDensityQualifier( + Density.getByIndex(index))); + } else { + // empty selection, means no qualifier. // Since the qualifier classes are immutable, and we don't want to // remove the qualifier from the configuration, we create a new default one. - mSelectedConfiguration.setPixelDensityQualifier(new PixelDensityQualifier()); - } else { - try { - PixelDensityQualifier qualifier = PixelDensityQualifier.getQualifier( - PixelDensityQualifier.getFolderSegment(Integer.parseInt(value))); - if (qualifier != null) { - mSelectedConfiguration.setPixelDensityQualifier(qualifier); - } else { - // Failure! Looks like the value is wrong - // (for instance a one letter string). - // We do nothing in this case. - return; - } - } catch (NumberFormatException nfe) { - // Looks like the code is not a number. This should not happen since the text - // field has a VerifyListener that prevents it. - // We do nothing in this case. - return; - } + mSelectedConfiguration.setPixelDensityQualifier( + new PixelDensityQualifier()); } - + // notify of change onChange(true /* keepSelection */); - } + } @Override public void setQualifier(ResourceQualifier qualifier) { PixelDensityQualifier q = (PixelDensityQualifier)qualifier; - - mText.setText(Integer.toString(q.getValue())); + + Density value = q.getValue(); + if (value == null) { + mDensity.clearSelection(); + } else { + mDensity.select(Density.getIndex(value)); + } } } @@ -1202,7 +1198,7 @@ public class ConfigurationSelector extends Composite { } } } - + /** * Edit widget for {@link ScreenDimensionQualifier}. */ @@ -1217,9 +1213,9 @@ public class ConfigurationSelector extends Composite { ModifyListener modifyListener = new ModifyListener() { public void modifyText(ModifyEvent e) { onSizeChange(); - } + } }; - + FocusAdapter focusListener = new FocusAdapter() { @Override public void focusLost(FocusEvent e) { @@ -1237,12 +1233,12 @@ public class ConfigurationSelector extends Composite { mSize2.addModifyListener(modifyListener); mSize2.addFocusListener(focusListener); } - + private void onSizeChange() { // update the current config String size1 = mSize1.getText(); String size2 = mSize2.getText(); - + if (size1.length() == 0 || size2.length() == 0) { // if one of the strings is empty, reset to no qualifier. // Since the qualifier classes are immutable, and we don't want to @@ -1262,7 +1258,7 @@ public class ConfigurationSelector extends Composite { new ScreenDimensionQualifier()); } } - + // notify of change onChange(true /* keepSelection */); } @@ -1270,7 +1266,7 @@ public class ConfigurationSelector extends Composite { @Override public void setQualifier(ResourceQualifier qualifier) { ScreenDimensionQualifier q = (ScreenDimensionQualifier)qualifier; - + mSize1.setText(Integer.toString(q.getValue1())); mSize2.setText(Integer.toString(q.getValue2())); } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/NewXmlFileCreationPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/NewXmlFileCreationPage.java index 4edfb77..bd4e7a3 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/NewXmlFileCreationPage.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/NewXmlFileCreationPage.java @@ -897,6 +897,9 @@ class NewXmlFileCreationPage extends WizardPage { // enable types based on new API level enableTypesBasedOnApi(); + // update the folder name based on API level + resetFolderPath(false /*validate*/); + // update the Type with the new descriptors. initializeRootValues(); @@ -1023,7 +1026,7 @@ class NewXmlFileCreationPage extends WizardPage { // The configuration is valid. Reformat the folder path using the canonical // value from the configuration. - newPath = RES_FOLDER_ABS + mTempConfig.getFolderName(type.getResFolderType()); + newPath = RES_FOLDER_ABS + mTempConfig.getFolderName(type.getResFolderType(), mProject); } else { // The configuration is invalid. We still update the path but this time // do it manually on the string. @@ -1032,7 +1035,8 @@ class NewXmlFileCreationPage extends WizardPage { "^(" + RES_FOLDER_ABS +")[^-]*(.*)", //$NON-NLS-1$ //$NON-NLS-2$ "\\1" + type.getResFolderName() + "\\2"); //$NON-NLS-1$ //$NON-NLS-2$ } else { - newPath = RES_FOLDER_ABS + mTempConfig.getFolderName(type.getResFolderType()); + newPath = RES_FOLDER_ABS + mTempConfig.getFolderName(type.getResFolderType(), + mProject); } } @@ -1085,19 +1089,7 @@ class NewXmlFileCreationPage extends WizardPage { return; } - TypeInfo type = getSelectedType(); - - if (type != null) { - mConfigSelector.getConfiguration(mTempConfig); - StringBuffer sb = new StringBuffer(RES_FOLDER_ABS); - sb.append(mTempConfig.getFolderName(type.getResFolderType())); - - mInternalWsFolderPathUpdate = true; - mWsFolderPathTextField.setText(sb.toString()); - mInternalWsFolderPathUpdate = false; - - validatePage(); - } + resetFolderPath(true /*validate*/); } } @@ -1139,6 +1131,28 @@ class NewXmlFileCreationPage extends WizardPage { } /** + * Reset the current Folder path based on the UI selection + * @param validate if true, force a call to {@link #validatePage()}. + */ + private void resetFolderPath(boolean validate) { + TypeInfo type = getSelectedType(); + + if (type != null) { + mConfigSelector.getConfiguration(mTempConfig); + StringBuffer sb = new StringBuffer(RES_FOLDER_ABS); + sb.append(mTempConfig.getFolderName(type.getResFolderType(), mProject)); + + mInternalWsFolderPathUpdate = true; + mWsFolderPathTextField.setText(sb.toString()); + mInternalWsFolderPathUpdate = false; + + if (validate) { + validatePage(); + } + } + } + + /** * Validates the fields, displays errors and warnings. * Enables the finish button if there are no errors. */ diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/manager/ConfigMatchTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/manager/ConfigMatchTest.java index dd82bed..c93f2a2 100644 --- a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/manager/ConfigMatchTest.java +++ b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/manager/ConfigMatchTest.java @@ -34,6 +34,7 @@ import com.android.ide.eclipse.adt.internal.resources.manager.files.IFileWrapper import com.android.ide.eclipse.adt.internal.resources.manager.files.IFolderWrapper; import com.android.ide.eclipse.mock.FileMock; import com.android.ide.eclipse.mock.FolderMock; +import com.android.sdklib.SdkConstants; import java.lang.reflect.Field; import java.lang.reflect.Method; @@ -44,7 +45,7 @@ public class ConfigMatchTest extends TestCase { private static final String SEARCHED_FILENAME = "main.xml"; //$NON-NLS-1$ private static final String MISC1_FILENAME = "foo.xml"; //$NON-NLS-1$ private static final String MISC2_FILENAME = "bar.xml"; //$NON-NLS-1$ - + private ProjectResources mResources; private ResourceQualifier[] mQualifierList; private FolderConfiguration config4; @@ -55,20 +56,20 @@ public class ConfigMatchTest extends TestCase { @Override protected void setUp() throws Exception { super.setUp(); - + // create a Resource Manager to get a list of qualifier as instantiated by the real code. - // Thanks for QualifierListTest we know this contains all the qualifiers. + // Thanks for QualifierListTest we know this contains all the qualifiers. ResourceManager manager = ResourceManager.getInstance(); Field qualifierListField = ResourceManager.class.getDeclaredField("mQualifiers"); assertNotNull(qualifierListField); qualifierListField.setAccessible(true); - + // get the actual list. mQualifierList = (ResourceQualifier[])qualifierListField.get(manager); - + // create the project resources. mResources = new ProjectResources(false /* isFrameworkRepository */); - + // create 2 arrays of IResource. one with the filename being looked up, and one without. // Since the required API uses IResource, we can use MockFolder for them. FileMock[] validMemberList = new FileMock[] { @@ -80,7 +81,7 @@ public class ConfigMatchTest extends TestCase { new FileMock(MISC1_FILENAME), new FileMock(MISC2_FILENAME), }; - + // add multiple ResourceFolder to the project resource. FolderConfiguration defaultConfig = getConfiguration( null, // country code @@ -94,9 +95,9 @@ public class ConfigMatchTest extends TestCase { null, // text input null, // navigation null); // screen size - + addFolder(mResources, defaultConfig, validMemberList); - + config1 = getConfiguration( null, // country code null, // network code @@ -109,7 +110,7 @@ public class ConfigMatchTest extends TestCase { null, // text input null, // navigation null); // screen size - + addFolder(mResources, config1, validMemberList); config2 = getConfiguration( @@ -124,7 +125,7 @@ public class ConfigMatchTest extends TestCase { null, // text input null, // navigation null); // screen size - + addFolder(mResources, config2, validMemberList); config3 = getConfiguration( @@ -139,7 +140,7 @@ public class ConfigMatchTest extends TestCase { null, // text input null, // navigation null); // screen size - + addFolder(mResources, config3, validMemberList); config4 = getConfiguration( @@ -154,7 +155,7 @@ public class ConfigMatchTest extends TestCase { TextInputMethod.QWERTY.getValue(), // text input NavigationMethod.DPAD.getValue(), // navigation "480x320"); // screen size - + addFolder(mResources, config4, invalidMemberList); } @@ -177,10 +178,10 @@ public class ConfigMatchTest extends TestCase { TextInputMethod.QWERTY.getValue(), // text input NavigationMethod.DPAD.getValue(), // navigation "480x320"); // screen size - + ResourceFile result = mResources.getMatchingFile(SEARCHED_FILENAME, ResourceFolderType.LAYOUT, testConfig); - + boolean bresult = result.getFolder().getConfiguration().equals(config3); assertEquals(bresult, true); } @@ -193,10 +194,10 @@ public class ConfigMatchTest extends TestCase { */ private FolderConfiguration getConfiguration(String... qualifierValues) { FolderConfiguration config = new FolderConfiguration(); - + // those must be of the same length assertEquals(qualifierValues.length, mQualifierList.length); - + int index = 0; for (ResourceQualifier qualifier : mQualifierList) { @@ -208,7 +209,7 @@ public class ConfigMatchTest extends TestCase { return config; } - + /** * Adds a folder to the given {@link ProjectResources} with the given * {@link FolderConfiguration}. The folder is filled with files from the provided list. @@ -218,13 +219,10 @@ public class ConfigMatchTest extends TestCase { */ private void addFolder(ProjectResources resources, FolderConfiguration config, FileMock[] memberList) throws Exception { - + // figure out the folder name based on the configuration - String folderName = "layout"; - if (config.isDefault() == false) { - folderName += "-" + config.toString(); - } - + String folderName = config.getFolderName(ResourceFolderType.LAYOUT); + // create the folder mock FolderMock folder = new FolderMock(folderName, memberList); @@ -237,15 +235,15 @@ public class ConfigMatchTest extends TestCase { } } - /** Calls ProjectResource.add method via reflection to circumvent access - * restrictions that are enforced when running in the plug-in environment + /** Calls ProjectResource.add method via reflection to circumvent access + * restrictions that are enforced when running in the plug-in environment * ie cannot access package or protected members in a different plug-in, even * if they are in the same declared package as the accessor */ private ResourceFolder _addProjectResourceFolder(ProjectResources resources, FolderConfiguration config, FolderMock folder) throws Exception { - Method addMethod = ProjectResources.class.getDeclaredMethod("add", + Method addMethod = ProjectResources.class.getDeclaredMethod("add", ResourceFolderType.class, FolderConfiguration.class, IAbstractFolder.class); addMethod.setAccessible(true); @@ -253,7 +251,4 @@ public class ConfigMatchTest extends TestCase { ResourceFolderType.LAYOUT, config, new IFolderWrapper(folder)); return resFolder; } - - - } |