diff options
23 files changed, 1424 insertions, 1217 deletions
diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/HandleProfiling.java b/ddms/libs/ddmlib/src/com/android/ddmlib/HandleProfiling.java index e8e8103..0789655 100644 --- a/ddms/libs/ddmlib/src/com/android/ddmlib/HandleProfiling.java +++ b/ddms/libs/ddmlib/src/com/android/ddmlib/HandleProfiling.java @@ -73,11 +73,14 @@ final class HandleProfiling extends ChunkHandler { /** * Send a MPRS (Method PRofiling Start) request to the client. * + * The arguments to this method will eventually be passed to + * android.os.Debug.startMethodTracing() on the device. + * * @param fileName is the name of the file to which profiling data * will be written (on the device); it will have ".trace" * appended if necessary * @param bufferSize is the desired buffer size in bytes (8MB is good) - * @param flags should be zero + * @param flags see startMethodTracing() docs; use 0 for default behavior */ public static void sendMPRS(Client client, String fileName, int bufferSize, int flags) throws IOException { diff --git a/eclipse/features/com.android.ide.eclipse.adt/feature.xml b/eclipse/features/com.android.ide.eclipse.adt/feature.xml index 6dd3ee7..e4cc9f2 100644 --- a/eclipse/features/com.android.ide.eclipse.adt/feature.xml +++ b/eclipse/features/com.android.ide.eclipse.adt/feature.xml @@ -2,7 +2,7 @@ <feature id="com.android.ide.eclipse.adt" label="Android Development Tools" - version="0.9.3.qualifier" + version="0.9.4.qualifier" provider-name="The Android Open Source Project" plugin="com.android.ide.eclipse.adt"> diff --git a/eclipse/features/com.android.ide.eclipse.ddms/feature.xml b/eclipse/features/com.android.ide.eclipse.ddms/feature.xml index e67f960..c0cb12d 100644 --- a/eclipse/features/com.android.ide.eclipse.ddms/feature.xml +++ b/eclipse/features/com.android.ide.eclipse.ddms/feature.xml @@ -2,7 +2,7 @@ <feature id="com.android.ide.eclipse.ddms" label="Android DDMS" - version="0.9.3.qualifier" + version="0.9.4.qualifier" provider-name="The Android Open Source Project"> <description> diff --git a/eclipse/features/com.android.ide.eclipse.tests/feature.xml b/eclipse/features/com.android.ide.eclipse.tests/feature.xml index cc34045..679da31 100644 --- a/eclipse/features/com.android.ide.eclipse.tests/feature.xml +++ b/eclipse/features/com.android.ide.eclipse.tests/feature.xml @@ -2,7 +2,7 @@ <feature id="com.android.ide.eclipse.tests" label="ADT Tests" - version="0.9.3.qualifier" + version="0.9.4.qualifier" provider-name="The Android Open Source Project"> <copyright> diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/.gitignore b/eclipse/plugins/com.android.ide.eclipse.adt/.gitignore new file mode 100644 index 0000000..d392f0e --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.adt/.gitignore @@ -0,0 +1 @@ +*.jar diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/META-INF/MANIFEST.MF b/eclipse/plugins/com.android.ide.eclipse.adt/META-INF/MANIFEST.MF index 32c939b..e840e59 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/META-INF/MANIFEST.MF +++ b/eclipse/plugins/com.android.ide.eclipse.adt/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Android Development Toolkit Bundle-SymbolicName: com.android.ide.eclipse.adt;singleton:=true -Bundle-Version: 0.9.3.qualifier +Bundle-Version: 0.9.4.qualifier Bundle-ClassPath: ., jarutils.jar, androidprefs.jar, 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 225d5bd..0dfa0b4 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 @@ -20,6 +20,8 @@ import com.android.ide.eclipse.adt.AdtPlugin; import com.android.ide.eclipse.adt.internal.editors.IconFactory; import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditor.UiEditorActions; import com.android.ide.eclipse.adt.internal.editors.layout.LayoutReloadMonitor.ILayoutReloadListener; +import com.android.ide.eclipse.adt.internal.editors.layout.configuration.ConfigurationComposite; +import com.android.ide.eclipse.adt.internal.editors.layout.configuration.ConfigurationComposite.IConfigListener; import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.ViewElementDescriptor; import com.android.ide.eclipse.adt.internal.editors.layout.parts.ElementCreateCommand; import com.android.ide.eclipse.adt.internal.editors.layout.parts.UiElementEditPart; @@ -28,25 +30,9 @@ import com.android.ide.eclipse.adt.internal.editors.ui.tree.CopyCutAction; import com.android.ide.eclipse.adt.internal.editors.ui.tree.PasteAction; import com.android.ide.eclipse.adt.internal.editors.uimodel.UiDocumentNode; import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode; -import com.android.ide.eclipse.adt.internal.resources.ResourceType; -import com.android.ide.eclipse.adt.internal.resources.configurations.CountryCodeQualifier; import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration; -import com.android.ide.eclipse.adt.internal.resources.configurations.KeyboardStateQualifier; -import com.android.ide.eclipse.adt.internal.resources.configurations.LanguageQualifier; -import com.android.ide.eclipse.adt.internal.resources.configurations.NavigationMethodQualifier; -import com.android.ide.eclipse.adt.internal.resources.configurations.NetworkCodeQualifier; import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier; -import com.android.ide.eclipse.adt.internal.resources.configurations.RegionQualifier; -import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenDimensionQualifier; -import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier; -import com.android.ide.eclipse.adt.internal.resources.configurations.TextInputMethodQualifier; -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; import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResources; import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFile; import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFolderType; @@ -56,14 +42,10 @@ 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.DimensionVerifier; -import com.android.ide.eclipse.adt.internal.ui.ConfigurationSelector.LanguageRegionVerifier; -import com.android.ide.eclipse.adt.internal.ui.ConfigurationSelector.MobileCodeVerifier; import com.android.layoutlib.api.ILayoutLog; import com.android.layoutlib.api.ILayoutResult; import com.android.layoutlib.api.IProjectCallback; import com.android.layoutlib.api.IResourceValue; -import com.android.layoutlib.api.IStyleResourceValue; import com.android.layoutlib.api.IXmlPullParser; import com.android.layoutlib.api.ILayoutResult.ILayoutViewInfo; import com.android.sdklib.IAndroidTarget; @@ -97,22 +79,12 @@ import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.viewers.ISelection; import org.eclipse.swt.SWT; import org.eclipse.swt.dnd.Clipboard; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.ImageData; import org.eclipse.swt.graphics.PaletteData; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Text; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.PartInitException; import org.eclipse.ui.ide.IDE; @@ -127,12 +99,9 @@ import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Set; /** * Graphical layout editor, based on GEF. @@ -142,9 +111,8 @@ import java.util.Set; * To understand Drag'n'drop: http://www.eclipse.org/articles/Article-Workbench-DND/drag_drop.html */ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor - implements ILayoutReloadListener { + implements ILayoutReloadListener, IConfigListener { - private final static String THEME_SEPARATOR = "----------"; //$NON-NLS-1$ /** Reference to the layout editor */ private final LayoutEditor mLayoutEditor; @@ -154,43 +122,10 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor private Clipboard mClipboard; private Composite mParent; + private ConfigurationComposite mConfigComposite; + private PaletteRoot mPaletteRoot; - private Text mCountry; - private Text mNetwork; - private Combo mLanguage; - private Combo mRegion; - private Combo mOrientation; - private Combo mDensity; - private Combo mTouch; - private Combo mKeyboard; - private Combo mTextInput; - private Combo mNavigation; - private Text mSize1; - private Text mSize2; - private Combo mThemeCombo; - private Button mCreateButton; - - private Label mCountryIcon; - private Label mNetworkIcon; - private Label mLanguageIcon; - private Label mRegionIcon; - private Label mOrientationIcon; - private Label mDensityIcon; - private Label mTouchIcon; - private Label mKeyboardIcon; - private Label mTextInputIcon; - private Label mNavigationIcon; - private Label mSizeIcon; - - private Label mCurrentLayoutLabel; - - private Image mWarningImage; - private Image mMatchImage; - private Image mErrorImage; - - /** The {@link FolderConfiguration} representing the state of the UI controls */ - private FolderConfiguration mCurrentConfig = new FolderConfiguration(); /** The {@link FolderConfiguration} being edited. */ private FolderConfiguration mEditedConfig; @@ -201,8 +136,6 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor private boolean mNeedsXmlReload = false; private boolean mNeedsRecompute = false; - private int mPlatformThemeCount = 0; - private boolean mDisableUpdates = false; /** Listener to update the root node if the target of the file is changed because of a * SDK location change or a project target change */ @@ -217,9 +150,7 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor // because the SDK changed we must reset the configured framework resource. mConfiguredFrameworkRes = null; - updateUIFromResources(); - - mThemeCombo.getParent().layout(); + mConfigComposite.updateUIFromResources(); // updateUiFromFramework will reset language/region combo, so we must call // setConfiguration after, or the settext on language/region will be lost. @@ -247,21 +178,16 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor private final Runnable mUiUpdateFromResourcesRunnable = new Runnable() { public void run() { - updateUIFromResources(); - mThemeCombo.getParent().layout(); + mConfigComposite.updateUIFromResources(); } }; + public GraphicalLayoutEditor(LayoutEditor layoutEditor) { mLayoutEditor = layoutEditor; setEditDomain(new DefaultEditDomain(this)); setPartName("Layout"); - IconFactory factory = IconFactory.getInstance(); - mWarningImage = factory.getIcon("warning"); //$NON-NLS-1$ - mMatchImage = factory.getIcon("match"); //$NON-NLS-1$ - mErrorImage = factory.getIcon("error"); //$NON-NLS-1$ - AdtPlugin.getDefault().addTargetListener(mTargetListener); } @@ -273,7 +199,6 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor public void createPartControl(Composite parent) { mParent = parent; GridLayout gl; - GridData gd; mClipboard = new Clipboard(parent.getDisplay()); @@ -281,286 +206,7 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor gl.marginHeight = gl.marginWidth = 0; // create the top part for the configuration control - int cols = 10; - - Composite topParent = new Composite(parent, SWT.NONE); - topParent.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - topParent.setLayout(gl = new GridLayout(cols, false)); - - new Label(topParent, SWT.NONE).setText("MCC"); - mCountryIcon = createControlComposite(topParent, true /* grab_horizontal */); - mCountry = new Text(mCountryIcon.getParent(), SWT.BORDER); - mCountry.setLayoutData(new GridData( - GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL)); - mCountry.addVerifyListener(new MobileCodeVerifier()); - mCountry.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetDefaultSelected(SelectionEvent e) { - onCountryCodeChange(); - } - }); - mCountry.addModifyListener(new ModifyListener() { - public void modifyText(ModifyEvent e) { - onCountryCodeChange(); - } - }); - - new Label(topParent, SWT.NONE).setText("MNC"); - mNetworkIcon = createControlComposite(topParent, true /* grab_horizontal */); - mNetwork = new Text(mNetworkIcon.getParent(), SWT.BORDER); - mNetwork.setLayoutData(new GridData( - GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL)); - mNetwork.addVerifyListener(new MobileCodeVerifier()); - mNetwork.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetDefaultSelected(SelectionEvent e) { - onNetworkCodeChange(); - } - }); - mNetwork.addModifyListener(new ModifyListener() { - public void modifyText(ModifyEvent e) { - onNetworkCodeChange(); - } - }); - - new Label(topParent, SWT.NONE).setText("Lang"); - mLanguageIcon = createControlComposite(topParent, true /* grab_horizontal */); - mLanguage = new Combo(mLanguageIcon.getParent(), SWT.DROP_DOWN); - mLanguage.setLayoutData(new GridData( - GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL)); - mLanguage.addVerifyListener(new LanguageRegionVerifier()); - mLanguage.addSelectionListener(new SelectionListener() { - public void widgetDefaultSelected(SelectionEvent e) { - onLanguageChange(); - } - public void widgetSelected(SelectionEvent e) { - onLanguageChange(); - } - }); - mLanguage.addModifyListener(new ModifyListener() { - public void modifyText(ModifyEvent e) { - onLanguageChange(); - } - }); - - new Label(topParent, SWT.NONE).setText("Region"); - mRegionIcon = createControlComposite(topParent, true /* grab_horizontal */); - mRegion = new Combo(mRegionIcon.getParent(), SWT.DROP_DOWN); - mRegion.setLayoutData(new GridData( - GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL)); - mRegion.addVerifyListener(new LanguageRegionVerifier()); - mRegion.addSelectionListener(new SelectionListener() { - public void widgetDefaultSelected(SelectionEvent e) { - onRegionChange(); - } - public void widgetSelected(SelectionEvent e) { - onRegionChange(); - } - }); - mRegion.addModifyListener(new ModifyListener() { - public void modifyText(ModifyEvent e) { - onRegionChange(); - } - }); - - new Label(topParent, SWT.NONE).setText("Orient"); - mOrientationIcon = createControlComposite(topParent, true /* grab_horizontal */); - mOrientation = new Combo(mOrientationIcon.getParent(), SWT.DROP_DOWN | SWT.READ_ONLY); - ScreenOrientation[] soValues = ScreenOrientation.values(); - mOrientation.add("(Default)"); - for (ScreenOrientation value : soValues) { - mOrientation.add(value.getDisplayValue()); - } - mOrientation.select(0); - mOrientation.setLayoutData(new GridData( - GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL)); - mOrientation.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - onOrientationChange(); - } - }); - - new Label(topParent, SWT.NONE).setText("Density"); - mDensityIcon = createControlComposite(topParent, true /* grab_horizontal */); - 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.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - onDensityChange(); - } - }); - - new Label(topParent, SWT.NONE).setText("Touch"); - mTouchIcon = createControlComposite(topParent, true /* grab_horizontal */); - mTouch = new Combo(mTouchIcon.getParent(), SWT.DROP_DOWN | SWT.READ_ONLY); - TouchScreenType[] tstValues = TouchScreenType.values(); - mTouch.add("(Default)"); - for (TouchScreenType value : tstValues) { - mTouch.add(value.getDisplayValue()); - } - mTouch.select(0); - mTouch.setLayoutData(new GridData( - GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL)); - mTouch.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - onTouchChange(); - } - }); - - new Label(topParent, SWT.NONE).setText("Keybrd"); - mKeyboardIcon = createControlComposite(topParent, true /* grab_horizontal */); - mKeyboard = new Combo(mKeyboardIcon.getParent(), SWT.DROP_DOWN | SWT.READ_ONLY); - KeyboardState[] ksValues = KeyboardState.values(); - mKeyboard.add("(Default)"); - for (KeyboardState value : ksValues) { - mKeyboard.add(value.getDisplayValue()); - } - mKeyboard.select(0); - mKeyboard.setLayoutData(new GridData( - GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL)); - mKeyboard.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - onKeyboardChange(); - } - }); - - new Label(topParent, SWT.NONE).setText("Input"); - mTextInputIcon = createControlComposite(topParent, true /* grab_horizontal */); - mTextInput = new Combo(mTextInputIcon.getParent(), SWT.DROP_DOWN | SWT.READ_ONLY); - TextInputMethod[] timValues = TextInputMethod.values(); - mTextInput.add("(Default)"); - for (TextInputMethod value : timValues) { - mTextInput.add(value.getDisplayValue()); - } - mTextInput.select(0); - mTextInput.setLayoutData(new GridData( - GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL)); - mTextInput.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - onTextInputChange(); - } - }); - - new Label(topParent, SWT.NONE).setText("Nav"); - mNavigationIcon = createControlComposite(topParent, true /* grab_horizontal */); - mNavigation = new Combo(mNavigationIcon.getParent(), SWT.DROP_DOWN | SWT.READ_ONLY); - NavigationMethod[] nValues = NavigationMethod.values(); - mNavigation.add("(Default)"); - for (NavigationMethod value : nValues) { - mNavigation.add(value.getDisplayValue()); - } - mNavigation.select(0); - mNavigation.setLayoutData(new GridData( - GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL)); - mNavigation.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - onNavigationChange(); - } - }); - - Composite labelParent = new Composite(topParent, SWT.NONE); - labelParent.setLayout(gl = new GridLayout(8, false)); - gl.marginWidth = gl.marginHeight = 0; - labelParent.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL)); - gd.horizontalSpan = cols; - - new Label(labelParent, SWT.NONE).setText("Editing config:"); - mCurrentLayoutLabel = new Label(labelParent, SWT.NONE); - mCurrentLayoutLabel.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL)); - gd.widthHint = 50; - - new Label(labelParent, SWT.NONE).setText("Size"); - mSizeIcon = createControlComposite(labelParent, false); - Composite sizeParent = new Composite(mSizeIcon.getParent(), SWT.NONE); - sizeParent.setLayout(gl = new GridLayout(3, false)); - gl.marginWidth = gl.marginHeight = 0; - gl.horizontalSpacing = 0; - - mSize1 = new Text(sizeParent, SWT.BORDER); - mSize1.setLayoutData(gd = new GridData()); - gd.widthHint = 30; - new Label(sizeParent, SWT.NONE).setText("x"); - mSize2 = new Text(sizeParent, SWT.BORDER); - mSize2.setLayoutData(gd = new GridData()); - gd.widthHint = 30; - - DimensionVerifier verifier = new DimensionVerifier(); - mSize1.addVerifyListener(verifier); - mSize2.addVerifyListener(verifier); - - SelectionListener sl = new SelectionListener() { - public void widgetDefaultSelected(SelectionEvent e) { - onSizeChange(); - } - public void widgetSelected(SelectionEvent e) { - onSizeChange(); - } - }; - - mSize1.addSelectionListener(sl); - mSize2.addSelectionListener(sl); - - ModifyListener sizeModifyListener = new ModifyListener() { - public void modifyText(ModifyEvent e) { - onSizeChange(); - } - }; - - mSize1.addModifyListener(sizeModifyListener); - mSize2.addModifyListener(sizeModifyListener); - - // first separator - Label separator = new Label(labelParent, SWT.SEPARATOR | SWT.VERTICAL); - separator.setLayoutData(gd = new GridData( - GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_VERTICAL)); - gd.heightHint = 0; - - mThemeCombo = new Combo(labelParent, SWT.READ_ONLY | SWT.DROP_DOWN); - mThemeCombo.setEnabled(false); - updateUIFromResources(); - mThemeCombo.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - onThemeChange(); - } - }); - - // second separator - separator = new Label(labelParent, SWT.SEPARATOR | SWT.VERTICAL); - separator.setLayoutData(gd = new GridData( - GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_VERTICAL)); - gd.heightHint = 0; - - mCreateButton = new Button(labelParent, SWT.PUSH | SWT.FLAT); - mCreateButton.setText("Create..."); - mCreateButton.setEnabled(false); - mCreateButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - LayoutCreatorDialog dialog = new LayoutCreatorDialog(mCreateButton.getShell(), - mEditedFile.getName(), - Sdk.getCurrent().getTarget(mEditedFile.getProject()), mCurrentConfig); - if (dialog.open() == Dialog.OK) { - final FolderConfiguration config = new FolderConfiguration(); - dialog.getConfiguration(config); - - createAlternateLayout(config); - } - } - }); + mConfigComposite = new ConfigurationComposite(this, parent, SWT.NONE); // create a new composite that will contain the standard editor controls. Composite editorParent = new Composite(parent, SWT.NONE); @@ -689,7 +335,7 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor FileEditorInput fileInput = (FileEditorInput)input; mEditedFile = fileInput.getFile(); - updateUIFromResources(); + mConfigComposite.updateUIFromResources(); LayoutReloadMonitor.getMonitor().addListener(mEditedFile.getProject(), this); } else { @@ -873,49 +519,12 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor setConfiguration(configuration, true /*force*/); // enable the create button if the current and edited config are not equals - mCreateButton.setEnabled(mEditedConfig.equals(mCurrentConfig) == false); + mConfigComposite.setEnabledCreate( + mEditedConfig.equals(mConfigComposite.getCurrentConfig()) == false); } public Rectangle getBounds() { - ScreenOrientation orientation = null; - if (mOrientation.getSelectionIndex() == 0) { - orientation = ScreenOrientation.PORTRAIT; - } else { - orientation = ScreenOrientation.getByIndex( - mOrientation.getSelectionIndex() - 1); - } - - int s1, s2; - - // get the size from the UI controls. If it fails, revert to default values. - try { - s1 = Integer.parseInt(mSize1.getText().trim()); - } catch (NumberFormatException e) { - s1 = 480; - } - - try { - s2 = Integer.parseInt(mSize2.getText().trim()); - } catch (NumberFormatException e) { - s2 = 320; - } - - // make sure s1 is bigger than s2 - if (s1 < s2) { - int tmp = s1; - s1 = s2; - s2 = tmp; - } - - switch (orientation) { - default: - case PORTRAIT: - return new Rectangle(0, 0, s2, s1); - case LANDSCAPE: - return new Rectangle(0, 0, s1, s2); - case SQUARE: - return new Rectangle(0, 0, s1, s1); - } + return mConfigComposite.getScreenBounds(); } /** @@ -960,7 +569,8 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor projectRes.loadAll(); // get the project resource values based on the current config - mConfiguredProjectRes = projectRes.getConfiguredResources(mCurrentConfig); + mConfiguredProjectRes = projectRes.getConfiguredResources( + mConfigComposite.getCurrentConfig()); } configuredProjectResources = mConfiguredProjectRes; @@ -975,17 +585,15 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor if (configuredProjectResources != null && frameworkResources != null) { // get the selected theme - int themeIndex = mThemeCombo.getSelectionIndex(); - if (themeIndex != -1) { - String theme = mThemeCombo.getItem(themeIndex); - + String theme = mConfigComposite.getTheme(); + if (theme != null) { // Render a single object as described by the ViewElementDescriptor. WidgetPullParser parser = new WidgetPullParser(descriptor); ILayoutResult result = computeLayout(bridge, parser, null /* projectKey */, 300 /* width */, 300 /* height */, 160 /*density*/, 160.f /*xdpi*/, 160.f /*ydpi*/, theme, - themeIndex >= mPlatformThemeCount /*isProjectTheme*/, + mConfigComposite.isProjectTheme(), configuredProjectResources, frameworkResources, projectCallback, null /* logger */); @@ -1080,231 +688,13 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor * @param force Whether the UI should be changed to exactly match the received configuration. */ void setConfiguration(FolderConfiguration config, boolean force) { - mDisableUpdates = true; // we do not want to trigger onXXXChange when setting new values in the widgets. - mEditedConfig = config; mConfiguredFrameworkRes = mConfiguredProjectRes = null; - mCountryIcon.setImage(mMatchImage); - CountryCodeQualifier countryQualifier = config.getCountryCodeQualifier(); - if (countryQualifier != null) { - mCountry.setText(String.format("%1$d", countryQualifier.getCode())); - mCurrentConfig.setCountryCodeQualifier(countryQualifier); - } else if (force) { - mCountry.setText(""); //$NON-NLS-1$ - mCurrentConfig.setCountryCodeQualifier(null); - } else if (mCountry.getText().length() > 0) { - mCountryIcon.setImage(mWarningImage); - } - - mNetworkIcon.setImage(mMatchImage); - NetworkCodeQualifier networkQualifier = config.getNetworkCodeQualifier(); - if (networkQualifier != null) { - mNetwork.setText(String.format("%1$d", networkQualifier.getCode())); - mCurrentConfig.setNetworkCodeQualifier(networkQualifier); - } else if (force) { - mNetwork.setText(""); //$NON-NLS-1$ - mCurrentConfig.setNetworkCodeQualifier(null); - } else if (mNetwork.getText().length() > 0) { - mNetworkIcon.setImage(mWarningImage); - } - - mLanguageIcon.setImage(mMatchImage); - LanguageQualifier languageQualifier = config.getLanguageQualifier(); - if (languageQualifier != null) { - mLanguage.setText(languageQualifier.getValue()); - mCurrentConfig.setLanguageQualifier(languageQualifier); - } else if (force) { - mLanguage.setText(""); //$NON-NLS-1$ - mCurrentConfig.setLanguageQualifier(null); - } else if (mLanguage.getText().length() > 0) { - mLanguageIcon.setImage(mWarningImage); - } + mConfigComposite.setConfiguration(config, force); - mRegionIcon.setImage(mMatchImage); - RegionQualifier regionQualifier = config.getRegionQualifier(); - if (regionQualifier != null) { - mRegion.setText(regionQualifier.getValue()); - mCurrentConfig.setRegionQualifier(regionQualifier); - } else if (force) { - mRegion.setText(""); //$NON-NLS-1$ - mCurrentConfig.setRegionQualifier(null); - } else if (mRegion.getText().length() > 0) { - mRegionIcon.setImage(mWarningImage); - } - - mOrientationIcon.setImage(mMatchImage); - ScreenOrientationQualifier orientationQualifier = config.getScreenOrientationQualifier(); - if (orientationQualifier != null) { - mOrientation.select( - ScreenOrientation.getIndex(orientationQualifier.getValue()) + 1); - mCurrentConfig.setScreenOrientationQualifier(orientationQualifier); - } else if (force) { - mOrientation.select(0); - mCurrentConfig.setScreenOrientationQualifier(null); - } else if (mOrientation.getSelectionIndex() != 0) { - mOrientationIcon.setImage(mWarningImage); - } - - mDensityIcon.setImage(mMatchImage); - PixelDensityQualifier densityQualifier = config.getPixelDensityQualifier(); - if (densityQualifier != null) { - mDensity.select( - Density.getIndex(densityQualifier.getValue()) + 1); - mCurrentConfig.setPixelDensityQualifier(densityQualifier); - } else if (force) { - mOrientation.select(0); - mCurrentConfig.setPixelDensityQualifier(null); - } else if (mDensity.getSelectionIndex() != 0) { - mDensityIcon.setImage(mWarningImage); - } - - mTouchIcon.setImage(mMatchImage); - TouchScreenQualifier touchQualifier = config.getTouchTypeQualifier(); - if (touchQualifier != null) { - mTouch.select(TouchScreenType.getIndex(touchQualifier.getValue()) + 1); - mCurrentConfig.setTouchTypeQualifier(touchQualifier); - } else if (force) { - mTouch.select(0); - mCurrentConfig.setTouchTypeQualifier(null); - } else if (mTouch.getSelectionIndex() != 0) { - mTouchIcon.setImage(mWarningImage); - } - - mKeyboardIcon.setImage(mMatchImage); - KeyboardStateQualifier keyboardQualifier = config.getKeyboardStateQualifier(); - if (keyboardQualifier != null) { - mKeyboard.select(KeyboardState.getIndex(keyboardQualifier.getValue()) + 1); - mCurrentConfig.setKeyboardStateQualifier(keyboardQualifier); - } else if (force) { - mKeyboard.select(0); - mCurrentConfig.setKeyboardStateQualifier(null); - } else if (mKeyboard.getSelectionIndex() != 0) { - mKeyboardIcon.setImage(mWarningImage); - } - - mTextInputIcon.setImage(mMatchImage); - TextInputMethodQualifier inputQualifier = config.getTextInputMethodQualifier(); - if (inputQualifier != null) { - mTextInput.select(TextInputMethod.getIndex(inputQualifier.getValue()) + 1); - mCurrentConfig.setTextInputMethodQualifier(inputQualifier); - } else if (force) { - mTextInput.select(0); - mCurrentConfig.setTextInputMethodQualifier(null); - } else if (mTextInput.getSelectionIndex() != 0) { - mTextInputIcon.setImage(mWarningImage); - } - - mNavigationIcon.setImage(mMatchImage); - NavigationMethodQualifier navigationQualifiter = config.getNavigationMethodQualifier(); - if (navigationQualifiter != null) { - mNavigation.select( - NavigationMethod.getIndex(navigationQualifiter.getValue()) + 1); - mCurrentConfig.setNavigationMethodQualifier(navigationQualifiter); - } else if (force) { - mNavigation.select(0); - mCurrentConfig.setNavigationMethodQualifier(null); - } else if (mNavigation.getSelectionIndex() != 0) { - mNavigationIcon.setImage(mWarningImage); - } - - mSizeIcon.setImage(mMatchImage); - ScreenDimensionQualifier sizeQualifier = config.getScreenDimensionQualifier(); - if (sizeQualifier != null) { - mSize1.setText(String.format("%1$d", sizeQualifier.getValue1())); - mSize2.setText(String.format("%1$d", sizeQualifier.getValue2())); - mCurrentConfig.setScreenDimensionQualifier(sizeQualifier); - } else if (force) { - mSize1.setText(""); //$NON-NLS-1$ - mSize2.setText(""); //$NON-NLS-1$ - mCurrentConfig.setScreenDimensionQualifier(null); - } else if (mSize1.getText().length() > 0 && mSize2.getText().length() > 0) { - mSizeIcon.setImage(mWarningImage); - } - - // 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. - */ - void displayConfigError() { - mCountryIcon.setImage(mMatchImage); - CountryCodeQualifier countryQualifier = mCurrentConfig.getCountryCodeQualifier(); - 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) { - mKeyboardIcon.setImage(mErrorImage); - } - - mTextInputIcon.setImage(mMatchImage); - TextInputMethodQualifier inputQualifier = mCurrentConfig.getTextInputMethodQualifier(); - 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)"); - } @Override UiDocumentNode getModel() { @@ -1316,275 +706,13 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor PaletteFactory.createPaletteRoot(mPaletteRoot, mLayoutEditor.getTargetData()); } - private void onCountryCodeChange() { - // because mCountry triggers onCountryCodeChange at each modification, calling setText() - // will trigger notifications, and we don't want that. - if (mDisableUpdates == true) { - return; - } - - // update the current config - String value = mCountry.getText(); - - // empty string, means no qualifier. - if (value.length() == 0) { - mCurrentConfig.setCountryCodeQualifier(null); - } else { - try { - CountryCodeQualifier qualifier = CountryCodeQualifier.getQualifier( - CountryCodeQualifier.getFolderSegment(Integer.parseInt(value))); - if (qualifier != null) { - mCurrentConfig.setCountryCodeQualifier(qualifier); - } else { - // Failure! Looks like the value is wrong (for instance a one letter string). - // We do nothing in this case. - mCountryIcon.setImage(mErrorImage); - 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. - mCurrentConfig.setCountryCodeQualifier(null); - mCountryIcon.setImage(mErrorImage); - } - } - - // look for a file to open/create - onConfigurationChange(); - } - - private void onNetworkCodeChange() { - // because mNetwork triggers onNetworkCodeChange at each modification, calling setText() - // will trigger notifications, and we don't want that. - if (mDisableUpdates == true) { - return; - } - - // update the current config - String value = mNetwork.getText(); - - // empty string, means no qualifier. - if (value.length() == 0) { - mCurrentConfig.setNetworkCodeQualifier(null); - } else { - try { - NetworkCodeQualifier qualifier = NetworkCodeQualifier.getQualifier( - NetworkCodeQualifier.getFolderSegment(Integer.parseInt(value))); - if (qualifier != null) { - mCurrentConfig.setNetworkCodeQualifier(qualifier); - } else { - // Failure! Looks like the value is wrong (for instance a one letter string). - // We do nothing in this case. - mNetworkIcon.setImage(mErrorImage); - 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. - mCurrentConfig.setNetworkCodeQualifier(null); - mNetworkIcon.setImage(mErrorImage); - } - } - - // look for a file to open/create - onConfigurationChange(); - } - - /** - * Call back for language combo selection - */ - private void onLanguageChange() { - // because mLanguage triggers onLanguageChange at each modification, the filling - // of the combo with data will trigger notifications, and we don't want that. - if (mDisableUpdates == true) { - return; - } - - // update the current config - String value = mLanguage.getText(); - - updateRegionUi(null /* projectResources */, null /* frameworkResources */); - - // empty string, means no qualifier. - if (value.length() == 0) { - mCurrentConfig.setLanguageQualifier(null); - } else { - LanguageQualifier qualifier = null; - String segment = LanguageQualifier.getFolderSegment(value); - if (segment != null) { - qualifier = LanguageQualifier.getQualifier(segment); - } - - if (qualifier != null) { - mCurrentConfig.setLanguageQualifier(qualifier); - } else { - // Failure! Looks like the value is wrong (for instance a one letter string). - mCurrentConfig.setLanguageQualifier(null); - mLanguageIcon.setImage(mErrorImage); - } - } - - // look for a file to open/create - onConfigurationChange(); - } - - private void onRegionChange() { - // because mRegion triggers onRegionChange at each modification, the filling - // of the combo with data will trigger notifications, and we don't want that. - if (mDisableUpdates == true) { - return; - } - - // update the current config - String value = mRegion.getText(); - - // empty string, means no qualifier. - if (value.length() == 0) { - mCurrentConfig.setRegionQualifier(null); - } else { - RegionQualifier qualifier = null; - String segment = RegionQualifier.getFolderSegment(value); - if (segment != null) { - qualifier = RegionQualifier.getQualifier(segment); - } - - if (qualifier != null) { - mCurrentConfig.setRegionQualifier(qualifier); - } else { - // Failure! Looks like the value is wrong (for instance a one letter string). - mCurrentConfig.setRegionQualifier(null); - mRegionIcon.setImage(mErrorImage); - } - } - - // look for a file to open/create - onConfigurationChange(); - } - - private void onOrientationChange() { - // update the current config - int index = mOrientation.getSelectionIndex(); - if (index != 0) { - mCurrentConfig.setScreenOrientationQualifier(new ScreenOrientationQualifier( - ScreenOrientation.getByIndex(index-1))); - } else { - mCurrentConfig.setScreenOrientationQualifier(null); - } - - // look for a file to open/create - onConfigurationChange(); - } - - private void onDensityChange() { - int index = mDensity.getSelectionIndex(); - if (index != 0) { - mCurrentConfig.setPixelDensityQualifier((new PixelDensityQualifier( - Density.getByIndex(index-1)))); - } else { - mCurrentConfig.setPixelDensityQualifier(null); - } - - // look for a file to open/create - onConfigurationChange(); - } - - private void onTouchChange() { - // update the current config - int index = mTouch.getSelectionIndex(); - if (index != 0) { - mCurrentConfig.setTouchTypeQualifier(new TouchScreenQualifier( - TouchScreenType.getByIndex(index-1))); - } else { - mCurrentConfig.setTouchTypeQualifier(null); - } - - // look for a file to open/create - onConfigurationChange(); - } - - private void onKeyboardChange() { - // update the current config - int index = mKeyboard.getSelectionIndex(); - if (index != 0) { - mCurrentConfig.setKeyboardStateQualifier(new KeyboardStateQualifier( - KeyboardState.getByIndex(index-1))); - } else { - mCurrentConfig.setKeyboardStateQualifier(null); - } - - // look for a file to open/create - onConfigurationChange(); - } - - private void onTextInputChange() { - // update the current config - int index = mTextInput.getSelectionIndex(); - if (index != 0) { - mCurrentConfig.setTextInputMethodQualifier(new TextInputMethodQualifier( - TextInputMethod.getByIndex(index-1))); - } else { - mCurrentConfig.setTextInputMethodQualifier(null); - } - - // look for a file to open/create - onConfigurationChange(); - } - - private void onNavigationChange() { - // update the current config - int index = mNavigation.getSelectionIndex(); - if (index != 0) { - mCurrentConfig.setNavigationMethodQualifier(new NavigationMethodQualifier( - NavigationMethod.getByIndex(index-1))); - } else { - mCurrentConfig.setNavigationMethodQualifier(null); - } - - // look for a file to open/create - onConfigurationChange(); - } - - private void onSizeChange() { - // because mSize1 and mSize2 trigger onSizeChange at each modification, calling setText() - // will trigger notifications, and we don't want that. - if (mDisableUpdates == true) { - return; - } - - // update the current config - String size1 = mSize1.getText(); - String size2 = mSize2.getText(); - - // if only one of the strings is empty, do nothing - if ((size1.length() == 0) ^ (size2.length() == 0)) { - mSizeIcon.setImage(mErrorImage); - return; - } else if (size1.length() == 0 && size2.length() == 0) { - // both sizes are empty: remove the qualifier. - mCurrentConfig.setScreenDimensionQualifier(null); - } else { - ScreenDimensionQualifier qualifier = ScreenDimensionQualifier.getQualifier(size1, - size2); - - if (qualifier != null) { - mCurrentConfig.setScreenDimensionQualifier(qualifier); - } else { - // Failure! Looks like the value is wrong. - // we do nothing in this case. - return; - } - } - - // look for a file to open/create - onConfigurationChange(); - } /** * Looks for a file matching the new {@link FolderConfiguration} and attempts to open it. * <p/>If there is no match, notify the user. */ - private void onConfigurationChange() { + public void onConfigurationChange() { mConfiguredFrameworkRes = mConfiguredProjectRes = null; if (mEditedFile == null || mEditedConfig == null) { @@ -1600,7 +728,7 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor if (resources != null) { match = resources.getMatchingFile(mEditedFile.getName(), ResourceFolderType.LAYOUT, - mCurrentConfig); + mConfigComposite.getCurrentConfig()); } if (match != null) { @@ -1623,65 +751,46 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor setConfiguration(mEditedConfig, false /*force*/); // enable the create button if the current and edited config are not equals - mCreateButton.setEnabled(mEditedConfig.equals(mCurrentConfig) == false); + mConfigComposite.setEnabledCreate( + mEditedConfig.equals(mConfigComposite.getCurrentConfig()) == false); // Even though the layout doesn't change, the config changed, and referenced // resources need to be updated. recomputeLayout(); } else { // update the configuration icons with the new edited config. - displayConfigError(); + mConfigComposite.displayConfigError(); // enable the Create button - mCreateButton.setEnabled(true); + mConfigComposite.setEnabledCreate(true); // display the error. + FolderConfiguration currentConfig = mConfigComposite.getCurrentConfig(); 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, + currentConfig.toDisplayString(), + currentConfig.getFolderName(ResourceFolderType.LAYOUT, Sdk.getCurrent().getTarget(mEditedFile.getProject())), mEditedFile.getName()); showErrorInEditor(message); } } - private void onThemeChange() { - int themeIndex = mThemeCombo.getSelectionIndex(); - if (themeIndex != -1) { - String theme = mThemeCombo.getItem(themeIndex); - - if (theme.equals(THEME_SEPARATOR)) { - mThemeCombo.select(0); - } - - recomputeLayout(); - } + public void onThemeChange() { + recomputeLayout(); } - /** - * Creates a composite with no margin/spacing, and puts a {@link Label} in it with the matching - * icon. - * @param parent the parent to receive the composite - * @return the created {@link Label} object. - */ - private Label createControlComposite(Composite parent, boolean grab) { - GridLayout gl; + public void onCreate() { + LayoutCreatorDialog dialog = new LayoutCreatorDialog(mParent.getShell(), + mEditedFile.getName(), + Sdk.getCurrent().getTarget(mEditedFile.getProject()), + mConfigComposite.getCurrentConfig()); + if (dialog.open() == Dialog.OK) { + final FolderConfiguration config = new FolderConfiguration(); + dialog.getConfiguration(config); - Composite composite = new Composite(parent, SWT.NONE); - composite.setLayout(gl = new GridLayout(2, false)); - gl.marginHeight = gl.marginWidth = 0; - gl.horizontalSpacing = 0; - if (grab) { - composite.setLayoutData( - new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL)); + createAlternateLayout(config); } - - // create the label - Label icon = new Label(composite, SWT.NONE); - icon.setImage(mMatchImage); - - return icon; } /** @@ -1760,19 +869,14 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor } // 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); - } + Map<String, Map<String, IResourceValue>> configuredProjectRes = + getConfiguredProjectResources(); // get the framework resources Map<String, Map<String, IResourceValue>> frameworkResources = getConfiguredFrameworkResources(); - if (mConfiguredProjectRes != null && frameworkResources != null) { + if (configuredProjectRes != null && frameworkResources != null) { if (mProjectCallback == null) { mProjectCallback = new ProjectCallback( bridge.classLoader, projectRes, iProject); @@ -1801,19 +905,19 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor } // get the selected theme - int themeIndex = mThemeCombo.getSelectionIndex(); - if (themeIndex != -1) { - String theme = mThemeCombo.getItem(themeIndex); + String theme = mConfigComposite.getTheme(); + if (theme != null) { // Compute the layout UiElementPullParser parser = new UiElementPullParser(getModel()); Rectangle rect = getBounds(); - boolean isProjectTheme = themeIndex >= mPlatformThemeCount; + boolean isProjectTheme = mConfigComposite.isProjectTheme(); // 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(); + PixelDensityQualifier qual = + mConfigComposite.getCurrentConfig().getPixelDensityQualifier(); if (qual != null) { int d = qual.getValue().getDpiValue(); if (d > 0) { @@ -1825,7 +929,7 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor iProject /* projectKey */, rect.width, rect.height, density, density, density, theme, isProjectTheme, - mConfiguredProjectRes, frameworkResources, mProjectCallback, + configuredProjectRes, frameworkResources, mProjectCallback, mLogger); // update the UiElementNode with the layout info. @@ -1985,260 +1089,71 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor // nothing to be done here for now. } - /** - * Updates the UI from values in the resources, such as languages, regions, themes, etc... - * This must be called from the UI thread. - */ - private void updateUIFromResources() { - - ResourceManager manager = ResourceManager.getInstance(); - - 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(); - if (name.startsWith("Theme.") || name.equals("Theme")) { - themes.add(value.getName()); - mPlatformThemeCount++; - } - } - - // sort them and add them to the combo - Collections.sort(themes); - - for (String theme : themes) { - mThemeCombo.add(theme); - } - - mPlatformThemeCount = themes.size(); - themes.clear(); - } - // now get the languages from the framework. - Set<String> frameworkLanguages = frameworkProject.getLanguages(); - if (frameworkLanguages != null) { - languages.addAll(frameworkLanguages); - } - } - - // now get the themes and languages from the project. - ProjectResources project = null; - if (mEditedFile != null) { - project = manager.getProjectResources(mEditedFile.getProject()); - - // 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 - if (mConfiguredProjectRes == null) { - // make sure they are loaded - project.loadAll(); - - // 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. - for (IResourceValue value : styleMap.values()) { - if (isTheme(value, styleMap)) { - themes.add(value.getName()); - } - } - - // sort them and add them the to the combo. - if (mPlatformThemeCount > 0 && themes.size() > 0) { - mThemeCombo.add(THEME_SEPARATOR); - } - - Collections.sort(themes); - - for (String theme : themes) { - mThemeCombo.add(theme); - } - } - } + public Map<String, Map<String, IResourceValue>> getConfiguredFrameworkResources() { + if (mConfiguredFrameworkRes == null) { + ProjectResources frameworkRes = getFrameworkResources(); - // now get the languages from the project. - Set<String> projectLanguages = project.getLanguages(); - if (projectLanguages != null) { - languages.addAll(projectLanguages); - } + if (frameworkRes == null) { + AdtPlugin.log(IStatus.ERROR, "Failed to get ProjectResource for the framework"); } - } - // add the languages to the Combo - for (String language : languages) { - mLanguage.add(language); + // get the framework resource values based on the current config + mConfiguredFrameworkRes = frameworkRes.getConfiguredResources( + mConfigComposite.getCurrentConfig()); } - mDisableUpdates = false; - - // and update the Region UI based on the current language - updateRegionUi(project, frameworkProject); - - // handle default selection of themes - if (mThemeCombo.getItemCount() > 0) { - mThemeCombo.setEnabled(true); - if (selection == -1) { - selection = 0; - } - - if (mThemeCombo.getItemCount() <= selection) { - mThemeCombo.select(0); - } else { - mThemeCombo.select(selection); - } - } else { - mThemeCombo.setEnabled(false); - } + return mConfiguredFrameworkRes; } - /** - * Returns whether the given <var>style</var> is a theme. - * This is done by making sure the parent is a theme. - * @param value the style to check - * @param styleMap the map of styles for the current project. Key is the style name. - * @return True if the given <var>style</var> is a theme. - */ - 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) { - // if there is no specified parent style we look an implied one. - // For instance 'Theme.light' is implied child style of 'Theme', - // and 'Theme.light.fullscreen' is implied child style of 'Theme.light' - String name = style.getName(); - int index = name.lastIndexOf('.'); - if (index != -1) { - parentStyle = name.substring(0, index); - } - } else { - // remove the useless @ if it's there - if (parentStyle.startsWith("@")) { - parentStyle = parentStyle.substring(1); - } + public Map<String, Map<String, IResourceValue>> getConfiguredProjectResources() { + if (mConfiguredProjectRes == null) { + ProjectResources project = getProjectResources(); - // check for framework identifier. - if (parentStyle.startsWith("android:")) { - frameworkStyle = true; - parentStyle = parentStyle.substring("android:".length()); - } + // make sure they are loaded + project.loadAll(); - // at this point we could have the format style/<name>. we want only the name - if (parentStyle.startsWith("style/")) { - parentStyle = parentStyle.substring("style/".length()); - } - } - - if (frameworkStyle) { - // if the parent is a framework style, it has to be 'Theme' or 'Theme.*' - return parentStyle.equals("Theme") || parentStyle.startsWith("Theme."); - } else { - // if it's a project style, we check this is a theme. - value = styleMap.get(parentStyle); - if (value != null) { - return isTheme(value, styleMap); - } - } + // get the project resource values based on the current config + mConfiguredProjectRes = project.getConfiguredResources( + mConfigComposite.getCurrentConfig()); } - return false; + return mConfiguredProjectRes; } /** - * Update the Region UI widget based on the current language selection - * @param projectResources the project resources or {@code null}. - * @param frameworkResources the framework resource or {@code null} + * Returns a {@link ProjectResources} for the framework resources. + * @return the framework resources or null if not found. */ - private void updateRegionUi(ProjectResources projectResources, - ProjectResources frameworkResources) { - if (projectResources == null && mEditedFile != null) { - projectResources = ResourceManager.getInstance().getProjectResources( - mEditedFile.getProject()); - } - - if (frameworkResources == null) { - frameworkResources = getFrameworkResources(); - } - - String currentLanguage = mLanguage.getText(); - - Set<String> set = null; + public ProjectResources getFrameworkResources() { + if (mEditedFile != null) { + Sdk currentSdk = Sdk.getCurrent(); + if (currentSdk != null) { + IAndroidTarget target = currentSdk.getTarget(mEditedFile.getProject()); - if (projectResources != null) { - set = projectResources.getRegions(currentLanguage); - } + if (target != null) { + AndroidTargetData data = currentSdk.getTargetData(target); - if (frameworkResources != null) { - if (set != null) { - Set<String> set2 = frameworkResources.getRegions(currentLanguage); - set.addAll(set2); - } else { - set = frameworkResources.getRegions(currentLanguage); + if (data != null) { + return data.getFrameworkResources(); + } + } } } - if (set != null) { - mDisableUpdates = true; - - mRegion.removeAll(); - for (String region : set) { - mRegion.add(region); - } - - mDisableUpdates = false; - } + return null; } - private Map<String, Map<String, IResourceValue>> getConfiguredFrameworkResources() { - if (mConfiguredFrameworkRes == null) { - ProjectResources frameworkRes = getFrameworkResources(); - - if (frameworkRes == null) { - AdtPlugin.log(IStatus.ERROR, "Failed to get ProjectResource for the framework"); - } - - // get the framework resource values based on the current config - mConfiguredFrameworkRes = frameworkRes.getConfiguredResources(mCurrentConfig); + public ProjectResources getProjectResources() { + if (mEditedFile != null) { + ResourceManager manager = ResourceManager.getInstance(); + return manager.getProjectResources(mEditedFile.getProject()); } - return mConfiguredFrameworkRes; + return null; } /** - * Creates a new layout file from the specificed {@link FolderConfiguration}. + * Creates a new layout file from the specified {@link FolderConfiguration}. */ private void createAlternateLayout(final FolderConfiguration config) { new Job("Create Alternate Resource") { @@ -2295,7 +1210,7 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor // to trigger the edit of the new file. res.refreshLocal(IResource.DEPTH_INFINITE, new IProgressMonitor() { public void done() { - mCurrentConfig.set(config); + mConfigComposite.setConfig(config); mParent.getDisplay().asyncExec(new Runnable() { public void run() { onConfigurationChange(); @@ -2358,29 +1273,6 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor } /** - * Returns a {@link ProjectResources} for the framework resources. - * @return the framework resources or null if not found. - */ - private ProjectResources getFrameworkResources() { - if (mEditedFile != null) { - 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(); - } - } - } - } - - return null; - } - - /** * Computes a layout by calling the correct computeLayout method of ILayoutBridge based on * the implementation API level. */ @@ -2423,4 +1315,5 @@ public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor mLogger); } } + } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigurationComposite.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigurationComposite.java new file mode 100644 index 0000000..52dfd5c --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigurationComposite.java @@ -0,0 +1,1268 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Eclipse Public License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.eclipse.org/org/documents/epl-v10.php + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ide.eclipse.adt.internal.editors.layout.configuration; + +import com.android.ide.eclipse.adt.internal.editors.IconFactory; +import com.android.ide.eclipse.adt.internal.resources.ResourceType; +import com.android.ide.eclipse.adt.internal.resources.configurations.CountryCodeQualifier; +import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration; +import com.android.ide.eclipse.adt.internal.resources.configurations.KeyboardStateQualifier; +import com.android.ide.eclipse.adt.internal.resources.configurations.LanguageQualifier; +import com.android.ide.eclipse.adt.internal.resources.configurations.NavigationMethodQualifier; +import com.android.ide.eclipse.adt.internal.resources.configurations.NetworkCodeQualifier; +import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier; +import com.android.ide.eclipse.adt.internal.resources.configurations.RegionQualifier; +import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenDimensionQualifier; +import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier; +import com.android.ide.eclipse.adt.internal.resources.configurations.TextInputMethodQualifier; +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; +import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResources; +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; +import com.android.layoutlib.api.IResourceValue; +import com.android.layoutlib.api.IStyleResourceValue; + +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +public class ConfigurationComposite extends Composite { + + private final static String THEME_SEPARATOR = "----------"; //$NON-NLS-1$ + + private Text mCountry; + private Text mNetwork; + private Combo mLanguage; + private Combo mRegion; + private Combo mOrientation; + private Combo mDensity; + private Combo mTouch; + private Combo mKeyboard; + private Combo mTextInput; + private Combo mNavigation; + private Text mSize1; + private Text mSize2; + private Combo mThemeCombo; + private Button mCreateButton; + + private Label mCountryIcon; + private Label mNetworkIcon; + private Label mLanguageIcon; + private Label mRegionIcon; + private Label mOrientationIcon; + private Label mDensityIcon; + private Label mTouchIcon; + private Label mKeyboardIcon; + private Label mTextInputIcon; + private Label mNavigationIcon; + private Label mSizeIcon; + + private Label mCurrentLayoutLabel; + + private Image mWarningImage; + private Image mMatchImage; + private Image mErrorImage; + + private int mPlatformThemeCount = 0; + private boolean mDisableUpdates = false; + + /** The {@link FolderConfiguration} representing the state of the UI controls */ + private final FolderConfiguration mCurrentConfig = new FolderConfiguration(); + private final IConfigListener mListener; + + public interface IConfigListener { + void onConfigurationChange(); + void onThemeChange(); + void onCreate(); + + ProjectResources getProjectResources(); + ProjectResources getFrameworkResources(); + Map<String, Map<String, IResourceValue>> getConfiguredProjectResources(); + Map<String, Map<String, IResourceValue>> getConfiguredFrameworkResources(); + } + + public ConfigurationComposite(IConfigListener listener, Composite parent, int style) { + super(parent, style); + mListener = listener; + + IconFactory factory = IconFactory.getInstance(); + mWarningImage = factory.getIcon("warning"); //$NON-NLS-1$ + mMatchImage = factory.getIcon("match"); //$NON-NLS-1$ + mErrorImage = factory.getIcon("error"); //$NON-NLS-1$ + + GridLayout gl; + GridData gd; + int cols = 10; + + setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + setLayout(gl = new GridLayout(cols, false)); + + new Label(this, SWT.NONE).setText("MCC"); + mCountryIcon = createControlComposite(this, true /* grab_horizontal */); + mCountry = new Text(mCountryIcon.getParent(), SWT.BORDER); + mCountry.setLayoutData(new GridData( + GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL)); + mCountry.addVerifyListener(new MobileCodeVerifier()); + mCountry.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetDefaultSelected(SelectionEvent e) { + onCountryCodeChange(); + } + }); + mCountry.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + onCountryCodeChange(); + } + }); + + new Label(this, SWT.NONE).setText("MNC"); + mNetworkIcon = createControlComposite(this, true /* grab_horizontal */); + mNetwork = new Text(mNetworkIcon.getParent(), SWT.BORDER); + mNetwork.setLayoutData(new GridData( + GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL)); + mNetwork.addVerifyListener(new MobileCodeVerifier()); + mNetwork.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetDefaultSelected(SelectionEvent e) { + onNetworkCodeChange(); + } + }); + mNetwork.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + onNetworkCodeChange(); + } + }); + + new Label(this, SWT.NONE).setText("Lang"); + mLanguageIcon = createControlComposite(this, true /* grab_horizontal */); + mLanguage = new Combo(mLanguageIcon.getParent(), SWT.DROP_DOWN); + mLanguage.setLayoutData(new GridData( + GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL)); + mLanguage.addVerifyListener(new LanguageRegionVerifier()); + mLanguage.addSelectionListener(new SelectionListener() { + public void widgetDefaultSelected(SelectionEvent e) { + onLanguageChange(); + } + public void widgetSelected(SelectionEvent e) { + onLanguageChange(); + } + }); + mLanguage.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + onLanguageChange(); + } + }); + + new Label(this, SWT.NONE).setText("Region"); + mRegionIcon = createControlComposite(this, true /* grab_horizontal */); + mRegion = new Combo(mRegionIcon.getParent(), SWT.DROP_DOWN); + mRegion.setLayoutData(new GridData( + GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL)); + mRegion.addVerifyListener(new LanguageRegionVerifier()); + mRegion.addSelectionListener(new SelectionListener() { + public void widgetDefaultSelected(SelectionEvent e) { + onRegionChange(); + } + public void widgetSelected(SelectionEvent e) { + onRegionChange(); + } + }); + mRegion.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + onRegionChange(); + } + }); + + new Label(this, SWT.NONE).setText("Orient"); + mOrientationIcon = createControlComposite(this, true /* grab_horizontal */); + mOrientation = new Combo(mOrientationIcon.getParent(), SWT.DROP_DOWN | SWT.READ_ONLY); + ScreenOrientation[] soValues = ScreenOrientation.values(); + mOrientation.add("(Default)"); + for (ScreenOrientation value : soValues) { + mOrientation.add(value.getDisplayValue()); + } + mOrientation.select(0); + mOrientation.setLayoutData(new GridData( + GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL)); + mOrientation.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + onOrientationChange(); + } + }); + + new Label(this, SWT.NONE).setText("Density"); + mDensityIcon = createControlComposite(this, true /* grab_horizontal */); + 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.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + onDensityChange(); + } + }); + + new Label(this, SWT.NONE).setText("Touch"); + mTouchIcon = createControlComposite(this, true /* grab_horizontal */); + mTouch = new Combo(mTouchIcon.getParent(), SWT.DROP_DOWN | SWT.READ_ONLY); + TouchScreenType[] tstValues = TouchScreenType.values(); + mTouch.add("(Default)"); + for (TouchScreenType value : tstValues) { + mTouch.add(value.getDisplayValue()); + } + mTouch.select(0); + mTouch.setLayoutData(new GridData( + GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL)); + mTouch.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + onTouchChange(); + } + }); + + new Label(this, SWT.NONE).setText("Keybrd"); + mKeyboardIcon = createControlComposite(this, true /* grab_horizontal */); + mKeyboard = new Combo(mKeyboardIcon.getParent(), SWT.DROP_DOWN | SWT.READ_ONLY); + KeyboardState[] ksValues = KeyboardState.values(); + mKeyboard.add("(Default)"); + for (KeyboardState value : ksValues) { + mKeyboard.add(value.getDisplayValue()); + } + mKeyboard.select(0); + mKeyboard.setLayoutData(new GridData( + GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL)); + mKeyboard.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + onKeyboardChange(); + } + }); + + new Label(this, SWT.NONE).setText("Input"); + mTextInputIcon = createControlComposite(this, true /* grab_horizontal */); + mTextInput = new Combo(mTextInputIcon.getParent(), SWT.DROP_DOWN | SWT.READ_ONLY); + TextInputMethod[] timValues = TextInputMethod.values(); + mTextInput.add("(Default)"); + for (TextInputMethod value : timValues) { + mTextInput.add(value.getDisplayValue()); + } + mTextInput.select(0); + mTextInput.setLayoutData(new GridData( + GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL)); + mTextInput.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + onTextInputChange(); + } + }); + + new Label(this, SWT.NONE).setText("Nav"); + mNavigationIcon = createControlComposite(this, true /* grab_horizontal */); + mNavigation = new Combo(mNavigationIcon.getParent(), SWT.DROP_DOWN | SWT.READ_ONLY); + NavigationMethod[] nValues = NavigationMethod.values(); + mNavigation.add("(Default)"); + for (NavigationMethod value : nValues) { + mNavigation.add(value.getDisplayValue()); + } + mNavigation.select(0); + mNavigation.setLayoutData(new GridData( + GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL)); + mNavigation.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + onNavigationChange(); + } + }); + + Composite labelParent = new Composite(this, SWT.NONE); + labelParent.setLayout(gl = new GridLayout(8, false)); + gl.marginWidth = gl.marginHeight = 0; + labelParent.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL)); + gd.horizontalSpan = cols; + + new Label(labelParent, SWT.NONE).setText("Editing config:"); + mCurrentLayoutLabel = new Label(labelParent, SWT.NONE); + mCurrentLayoutLabel.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL)); + gd.widthHint = 50; + + new Label(labelParent, SWT.NONE).setText("Size"); + mSizeIcon = createControlComposite(labelParent, false); + Composite sizeParent = new Composite(mSizeIcon.getParent(), SWT.NONE); + sizeParent.setLayout(gl = new GridLayout(3, false)); + gl.marginWidth = gl.marginHeight = 0; + gl.horizontalSpacing = 0; + + mSize1 = new Text(sizeParent, SWT.BORDER); + mSize1.setLayoutData(gd = new GridData()); + gd.widthHint = 30; + new Label(sizeParent, SWT.NONE).setText("x"); + mSize2 = new Text(sizeParent, SWT.BORDER); + mSize2.setLayoutData(gd = new GridData()); + gd.widthHint = 30; + + DimensionVerifier verifier = new DimensionVerifier(); + mSize1.addVerifyListener(verifier); + mSize2.addVerifyListener(verifier); + + SelectionListener sl = new SelectionListener() { + public void widgetDefaultSelected(SelectionEvent e) { + onSizeChange(); + } + public void widgetSelected(SelectionEvent e) { + onSizeChange(); + } + }; + + mSize1.addSelectionListener(sl); + mSize2.addSelectionListener(sl); + + ModifyListener sizeModifyListener = new ModifyListener() { + public void modifyText(ModifyEvent e) { + onSizeChange(); + } + }; + + mSize1.addModifyListener(sizeModifyListener); + mSize2.addModifyListener(sizeModifyListener); + + // first separator + Label separator = new Label(labelParent, SWT.SEPARATOR | SWT.VERTICAL); + separator.setLayoutData(gd = new GridData( + GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_VERTICAL)); + gd.heightHint = 0; + + mThemeCombo = new Combo(labelParent, SWT.READ_ONLY | SWT.DROP_DOWN); + mThemeCombo.setEnabled(false); + updateUIFromResources(); + mThemeCombo.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + onThemeChange(); + } + }); + + // second separator + separator = new Label(labelParent, SWT.SEPARATOR | SWT.VERTICAL); + separator.setLayoutData(gd = new GridData( + GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_VERTICAL)); + gd.heightHint = 0; + + mCreateButton = new Button(labelParent, SWT.PUSH | SWT.FLAT); + mCreateButton.setText("Create..."); + mCreateButton.setEnabled(false); + mCreateButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (mListener != null) { + mListener.onCreate(); + } + } + }); + + } + + public void setConfig(FolderConfiguration config) { + mCurrentConfig.set(config); + } + + public FolderConfiguration getCurrentConfig() { + return mCurrentConfig; + } + + public void getCurrentConfig(FolderConfiguration config) { + config.set(mCurrentConfig); + } + + public Rectangle getScreenBounds() { + ScreenOrientation orientation = null; + if (mOrientation.getSelectionIndex() == 0) { + orientation = ScreenOrientation.PORTRAIT; + } else { + orientation = ScreenOrientation.getByIndex( + mOrientation.getSelectionIndex() - 1); + } + + int s1, s2; + + // get the size from the UI controls. If it fails, revert to default values. + try { + s1 = Integer.parseInt(mSize1.getText().trim()); + } catch (NumberFormatException e) { + s1 = 480; + } + + try { + s2 = Integer.parseInt(mSize2.getText().trim()); + } catch (NumberFormatException e) { + s2 = 320; + } + + // make sure s1 is bigger than s2 + if (s1 < s2) { + int tmp = s1; + s1 = s2; + s2 = tmp; + } + + switch (orientation) { + default: + case PORTRAIT: + return new Rectangle(0, 0, s2, s1); + case LANDSCAPE: + return new Rectangle(0, 0, s1, s2); + case SQUARE: + return new Rectangle(0, 0, s1, s1); + } + } + + /** + * Updates the UI from values in the resources, such as languages, regions, themes, etc... + * This must be called from the UI thread. + */ + public void updateUIFromResources() { + if (mListener == null) { + return; // can't do anything w/o it. + } + + ProjectResources frameworkProject = mListener.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 = + mListener.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(); + if (name.startsWith("Theme.") || name.equals("Theme")) { + themes.add(value.getName()); + mPlatformThemeCount++; + } + } + + // sort them and add them to the combo + Collections.sort(themes); + + for (String theme : themes) { + mThemeCombo.add(theme); + } + + mPlatformThemeCount = themes.size(); + themes.clear(); + } + // now get the languages from the framework. + Set<String> frameworkLanguages = frameworkProject.getLanguages(); + if (frameworkLanguages != null) { + languages.addAll(frameworkLanguages); + } + } + + // now get the themes and languages from the project. + ProjectResources project = mListener.getProjectResources(); + // 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 + Map<String, Map<String, IResourceValue>> configuredProjectRes = + mListener.getConfiguredProjectResources(); + + if (configuredProjectRes != null) { + // get the styles. + Map<String, IResourceValue> styleMap = configuredProjectRes.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. + for (IResourceValue value : styleMap.values()) { + if (isTheme(value, styleMap)) { + themes.add(value.getName()); + } + } + + // sort them and add them the to the combo. + if (mPlatformThemeCount > 0 && themes.size() > 0) { + mThemeCombo.add(THEME_SEPARATOR); + } + + Collections.sort(themes); + + for (String theme : themes) { + mThemeCombo.add(theme); + } + } + } + + // now get the languages from the project. + Set<String> projectLanguages = project.getLanguages(); + if (projectLanguages != null) { + languages.addAll(projectLanguages); + } + } + + // add the languages to the Combo + for (String language : languages) { + mLanguage.add(language); + } + + mDisableUpdates = false; + + // and update the Region UI based on the current language + updateRegionUi(); + + // handle default selection of themes + if (mThemeCombo.getItemCount() > 0) { + mThemeCombo.setEnabled(true); + if (selection == -1) { + selection = 0; + } + + if (mThemeCombo.getItemCount() <= selection) { + mThemeCombo.select(0); + } else { + mThemeCombo.select(selection); + } + } else { + mThemeCombo.setEnabled(false); + } + + mThemeCombo.getParent().layout(); + } + + /** + * Returns the current theme, or null if the combo has no selection. + */ + public String getTheme() { + int themeIndex = mThemeCombo.getSelectionIndex(); + if (themeIndex != -1) { + return mThemeCombo.getItem(themeIndex); + } + + return null; + } + + /** + * Returns whether the current theme selection is a project theme. + * <p/>The returned value is meaningless if {@link #getTheme()} returns <code>null</code>. + * @return true for project theme, false for framework theme + */ + public boolean isProjectTheme() { + return mThemeCombo.getSelectionIndex() >= mPlatformThemeCount; + } + + + public void setEnabledCreate(boolean enabled) { + mCreateButton.setEnabled(enabled); + } + + /** + * Update the UI controls state with a given {@link FolderConfiguration}. + * <p/>If <var>force</var> is set to <code>true</code> the UI will be changed to exactly reflect + * <var>config</var>, otherwise, if a qualifier is not present in <var>config</var>, + * the UI control is not modified. However if the value in the control is not the default value, + * a warning icon is shown. + * @param config The {@link FolderConfiguration} to set. + * @param force Whether the UI should be changed to exactly match the received configuration. + */ + public void setConfiguration(FolderConfiguration config, boolean force) { + mDisableUpdates = true; // we do not want to trigger onXXXChange when setting new values in the widgets. + + mCountryIcon.setImage(mMatchImage); + CountryCodeQualifier countryQualifier = config.getCountryCodeQualifier(); + if (countryQualifier != null) { + mCountry.setText(String.format("%1$d", countryQualifier.getCode())); + mCurrentConfig.setCountryCodeQualifier(countryQualifier); + } else if (force) { + mCountry.setText(""); //$NON-NLS-1$ + mCurrentConfig.setCountryCodeQualifier(null); + } else if (mCountry.getText().length() > 0) { + mCountryIcon.setImage(mWarningImage); + } + + mNetworkIcon.setImage(mMatchImage); + NetworkCodeQualifier networkQualifier = config.getNetworkCodeQualifier(); + if (networkQualifier != null) { + mNetwork.setText(String.format("%1$d", networkQualifier.getCode())); + mCurrentConfig.setNetworkCodeQualifier(networkQualifier); + } else if (force) { + mNetwork.setText(""); //$NON-NLS-1$ + mCurrentConfig.setNetworkCodeQualifier(null); + } else if (mNetwork.getText().length() > 0) { + mNetworkIcon.setImage(mWarningImage); + } + + mLanguageIcon.setImage(mMatchImage); + LanguageQualifier languageQualifier = config.getLanguageQualifier(); + if (languageQualifier != null) { + mLanguage.setText(languageQualifier.getValue()); + mCurrentConfig.setLanguageQualifier(languageQualifier); + } else if (force) { + mLanguage.setText(""); //$NON-NLS-1$ + mCurrentConfig.setLanguageQualifier(null); + } else if (mLanguage.getText().length() > 0) { + mLanguageIcon.setImage(mWarningImage); + } + + mRegionIcon.setImage(mMatchImage); + RegionQualifier regionQualifier = config.getRegionQualifier(); + if (regionQualifier != null) { + mRegion.setText(regionQualifier.getValue()); + mCurrentConfig.setRegionQualifier(regionQualifier); + } else if (force) { + mRegion.setText(""); //$NON-NLS-1$ + mCurrentConfig.setRegionQualifier(null); + } else if (mRegion.getText().length() > 0) { + mRegionIcon.setImage(mWarningImage); + } + + mOrientationIcon.setImage(mMatchImage); + ScreenOrientationQualifier orientationQualifier = config.getScreenOrientationQualifier(); + if (orientationQualifier != null) { + mOrientation.select( + ScreenOrientation.getIndex(orientationQualifier.getValue()) + 1); + mCurrentConfig.setScreenOrientationQualifier(orientationQualifier); + } else if (force) { + mOrientation.select(0); + mCurrentConfig.setScreenOrientationQualifier(null); + } else if (mOrientation.getSelectionIndex() != 0) { + mOrientationIcon.setImage(mWarningImage); + } + + mDensityIcon.setImage(mMatchImage); + PixelDensityQualifier densityQualifier = config.getPixelDensityQualifier(); + if (densityQualifier != null) { + mDensity.select( + Density.getIndex(densityQualifier.getValue()) + 1); + mCurrentConfig.setPixelDensityQualifier(densityQualifier); + } else if (force) { + mDensity.select(0); + mCurrentConfig.setPixelDensityQualifier(null); + } else if (mDensity.getSelectionIndex() != 0) { + mDensityIcon.setImage(mWarningImage); + } + + mTouchIcon.setImage(mMatchImage); + TouchScreenQualifier touchQualifier = config.getTouchTypeQualifier(); + if (touchQualifier != null) { + mTouch.select(TouchScreenType.getIndex(touchQualifier.getValue()) + 1); + mCurrentConfig.setTouchTypeQualifier(touchQualifier); + } else if (force) { + mTouch.select(0); + mCurrentConfig.setTouchTypeQualifier(null); + } else if (mTouch.getSelectionIndex() != 0) { + mTouchIcon.setImage(mWarningImage); + } + + mKeyboardIcon.setImage(mMatchImage); + KeyboardStateQualifier keyboardQualifier = config.getKeyboardStateQualifier(); + if (keyboardQualifier != null) { + mKeyboard.select(KeyboardState.getIndex(keyboardQualifier.getValue()) + 1); + mCurrentConfig.setKeyboardStateQualifier(keyboardQualifier); + } else if (force) { + mKeyboard.select(0); + mCurrentConfig.setKeyboardStateQualifier(null); + } else if (mKeyboard.getSelectionIndex() != 0) { + mKeyboardIcon.setImage(mWarningImage); + } + + mTextInputIcon.setImage(mMatchImage); + TextInputMethodQualifier inputQualifier = config.getTextInputMethodQualifier(); + if (inputQualifier != null) { + mTextInput.select(TextInputMethod.getIndex(inputQualifier.getValue()) + 1); + mCurrentConfig.setTextInputMethodQualifier(inputQualifier); + } else if (force) { + mTextInput.select(0); + mCurrentConfig.setTextInputMethodQualifier(null); + } else if (mTextInput.getSelectionIndex() != 0) { + mTextInputIcon.setImage(mWarningImage); + } + + mNavigationIcon.setImage(mMatchImage); + NavigationMethodQualifier navigationQualifiter = config.getNavigationMethodQualifier(); + if (navigationQualifiter != null) { + mNavigation.select( + NavigationMethod.getIndex(navigationQualifiter.getValue()) + 1); + mCurrentConfig.setNavigationMethodQualifier(navigationQualifiter); + } else if (force) { + mNavigation.select(0); + mCurrentConfig.setNavigationMethodQualifier(null); + } else if (mNavigation.getSelectionIndex() != 0) { + mNavigationIcon.setImage(mWarningImage); + } + + mSizeIcon.setImage(mMatchImage); + ScreenDimensionQualifier sizeQualifier = config.getScreenDimensionQualifier(); + if (sizeQualifier != null) { + mSize1.setText(String.format("%1$d", sizeQualifier.getValue1())); + mSize2.setText(String.format("%1$d", sizeQualifier.getValue2())); + mCurrentConfig.setScreenDimensionQualifier(sizeQualifier); + } else if (force) { + mSize1.setText(""); //$NON-NLS-1$ + mSize2.setText(""); //$NON-NLS-1$ + mCurrentConfig.setScreenDimensionQualifier(null); + } else if (mSize1.getText().length() > 0 && mSize2.getText().length() > 0) { + mSizeIcon.setImage(mWarningImage); + } + + // 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. + */ + public void displayConfigError() { + mCountryIcon.setImage(mMatchImage); + CountryCodeQualifier countryQualifier = mCurrentConfig.getCountryCodeQualifier(); + 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) { + mKeyboardIcon.setImage(mErrorImage); + } + + mTextInputIcon.setImage(mMatchImage); + TextInputMethodQualifier inputQualifier = mCurrentConfig.getTextInputMethodQualifier(); + 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)"); + } + + + + private void onCountryCodeChange() { + // because mCountry triggers onCountryCodeChange at each modification, calling setText() + // will trigger notifications, and we don't want that. + if (mDisableUpdates == true) { + return; + } + + // update the current config + String value = mCountry.getText(); + + // empty string, means no qualifier. + if (value.length() == 0) { + mCurrentConfig.setCountryCodeQualifier(null); + } else { + try { + CountryCodeQualifier qualifier = CountryCodeQualifier.getQualifier( + CountryCodeQualifier.getFolderSegment(Integer.parseInt(value))); + if (qualifier != null) { + mCurrentConfig.setCountryCodeQualifier(qualifier); + } else { + // Failure! Looks like the value is wrong (for instance a one letter string). + // We do nothing in this case. + mCountryIcon.setImage(mErrorImage); + 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. + mCurrentConfig.setCountryCodeQualifier(null); + mCountryIcon.setImage(mErrorImage); + } + } + + if (mListener != null) { + mListener.onConfigurationChange(); + } + } + + private void onNetworkCodeChange() { + // because mNetwork triggers onNetworkCodeChange at each modification, calling setText() + // will trigger notifications, and we don't want that. + if (mDisableUpdates == true) { + return; + } + + // update the current config + String value = mNetwork.getText(); + + // empty string, means no qualifier. + if (value.length() == 0) { + mCurrentConfig.setNetworkCodeQualifier(null); + } else { + try { + NetworkCodeQualifier qualifier = NetworkCodeQualifier.getQualifier( + NetworkCodeQualifier.getFolderSegment(Integer.parseInt(value))); + if (qualifier != null) { + mCurrentConfig.setNetworkCodeQualifier(qualifier); + } else { + // Failure! Looks like the value is wrong (for instance a one letter string). + // We do nothing in this case. + mNetworkIcon.setImage(mErrorImage); + 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. + mCurrentConfig.setNetworkCodeQualifier(null); + mNetworkIcon.setImage(mErrorImage); + } + } + + if (mListener != null) { + mListener.onConfigurationChange(); + } + } + + /** + * Call back for language combo selection + */ + private void onLanguageChange() { + // because mLanguage triggers onLanguageChange at each modification, the filling + // of the combo with data will trigger notifications, and we don't want that. + if (mDisableUpdates == true) { + return; + } + + // update the current config + String value = mLanguage.getText(); + + updateRegionUi(); + + // empty string, means no qualifier. + if (value.length() == 0) { + mCurrentConfig.setLanguageQualifier(null); + } else { + LanguageQualifier qualifier = null; + String segment = LanguageQualifier.getFolderSegment(value); + if (segment != null) { + qualifier = LanguageQualifier.getQualifier(segment); + } + + if (qualifier != null) { + mCurrentConfig.setLanguageQualifier(qualifier); + } else { + // Failure! Looks like the value is wrong (for instance a one letter string). + mCurrentConfig.setLanguageQualifier(null); + mLanguageIcon.setImage(mErrorImage); + } + } + + if (mListener != null) { + mListener.onConfigurationChange(); + } + } + + private void onRegionChange() { + // because mRegion triggers onRegionChange at each modification, the filling + // of the combo with data will trigger notifications, and we don't want that. + if (mDisableUpdates == true) { + return; + } + + // update the current config + String value = mRegion.getText(); + + // empty string, means no qualifier. + if (value.length() == 0) { + mCurrentConfig.setRegionQualifier(null); + } else { + RegionQualifier qualifier = null; + String segment = RegionQualifier.getFolderSegment(value); + if (segment != null) { + qualifier = RegionQualifier.getQualifier(segment); + } + + if (qualifier != null) { + mCurrentConfig.setRegionQualifier(qualifier); + } else { + // Failure! Looks like the value is wrong (for instance a one letter string). + mCurrentConfig.setRegionQualifier(null); + mRegionIcon.setImage(mErrorImage); + } + } + + if (mListener != null) { + mListener.onConfigurationChange(); + } + } + + private void onOrientationChange() { + // update the current config + int index = mOrientation.getSelectionIndex(); + if (index != 0) { + mCurrentConfig.setScreenOrientationQualifier(new ScreenOrientationQualifier( + ScreenOrientation.getByIndex(index-1))); + } else { + mCurrentConfig.setScreenOrientationQualifier(null); + } + + if (mListener != null) { + mListener.onConfigurationChange(); + } + } + + private void onDensityChange() { + int index = mDensity.getSelectionIndex(); + if (index != 0) { + mCurrentConfig.setPixelDensityQualifier((new PixelDensityQualifier( + Density.getByIndex(index-1)))); + } else { + mCurrentConfig.setPixelDensityQualifier(null); + } + + if (mListener != null) { + mListener.onConfigurationChange(); + } + } + + private void onTouchChange() { + // update the current config + int index = mTouch.getSelectionIndex(); + if (index != 0) { + mCurrentConfig.setTouchTypeQualifier(new TouchScreenQualifier( + TouchScreenType.getByIndex(index-1))); + } else { + mCurrentConfig.setTouchTypeQualifier(null); + } + + if (mListener != null) { + mListener.onConfigurationChange(); + } + } + + private void onKeyboardChange() { + // update the current config + int index = mKeyboard.getSelectionIndex(); + if (index != 0) { + mCurrentConfig.setKeyboardStateQualifier(new KeyboardStateQualifier( + KeyboardState.getByIndex(index-1))); + } else { + mCurrentConfig.setKeyboardStateQualifier(null); + } + + if (mListener != null) { + mListener.onConfigurationChange(); + } + } + + private void onTextInputChange() { + // update the current config + int index = mTextInput.getSelectionIndex(); + if (index != 0) { + mCurrentConfig.setTextInputMethodQualifier(new TextInputMethodQualifier( + TextInputMethod.getByIndex(index-1))); + } else { + mCurrentConfig.setTextInputMethodQualifier(null); + } + + if (mListener != null) { + mListener.onConfigurationChange(); + } + } + + private void onNavigationChange() { + // update the current config + int index = mNavigation.getSelectionIndex(); + if (index != 0) { + mCurrentConfig.setNavigationMethodQualifier(new NavigationMethodQualifier( + NavigationMethod.getByIndex(index-1))); + } else { + mCurrentConfig.setNavigationMethodQualifier(null); + } + + if (mListener != null) { + mListener.onConfigurationChange(); + } + } + + private void onSizeChange() { + // because mSize1 and mSize2 trigger onSizeChange at each modification, calling setText() + // will trigger notifications, and we don't want that. + if (mDisableUpdates == true) { + return; + } + + // update the current config + String size1 = mSize1.getText(); + String size2 = mSize2.getText(); + + // if only one of the strings is empty, do nothing + if ((size1.length() == 0) ^ (size2.length() == 0)) { + mSizeIcon.setImage(mErrorImage); + return; + } else if (size1.length() == 0 && size2.length() == 0) { + // both sizes are empty: remove the qualifier. + mCurrentConfig.setScreenDimensionQualifier(null); + } else { + ScreenDimensionQualifier qualifier = ScreenDimensionQualifier.getQualifier(size1, + size2); + + if (qualifier != null) { + mCurrentConfig.setScreenDimensionQualifier(qualifier); + } else { + // Failure! Looks like the value is wrong. + // we do nothing in this case. + return; + } + } + + if (mListener != null) { + mListener.onConfigurationChange(); + } + } + + private void onThemeChange() { + int themeIndex = mThemeCombo.getSelectionIndex(); + if (themeIndex != -1) { + String theme = mThemeCombo.getItem(themeIndex); + + if (theme.equals(THEME_SEPARATOR)) { + mThemeCombo.select(0); + } + + if (mListener != null) { + mListener.onThemeChange(); + } + } + } + + /** + * Creates a composite with no margin/spacing, and puts a {@link Label} in it with the matching + * icon. + * @param parent the parent to receive the composite + * @return the created {@link Label} object. + */ + private Label createControlComposite(Composite parent, boolean grab) { + GridLayout gl; + + Composite composite = new Composite(parent, SWT.NONE); + composite.setLayout(gl = new GridLayout(2, false)); + gl.marginHeight = gl.marginWidth = 0; + gl.horizontalSpacing = 0; + if (grab) { + composite.setLayoutData( + new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL)); + } + + // create the label + Label icon = new Label(composite, SWT.NONE); + icon.setImage(mMatchImage); + + return icon; + } + + /** + * Update the Region UI widget based on the current language selection + * @param projectResources the project resources or {@code null}. + * @param frameworkResources the framework resource or {@code null} + */ + private void updateRegionUi() { + if (mListener == null) { + return; + } + + ProjectResources projectResources = mListener.getProjectResources(); + ProjectResources frameworkResources = mListener.getFrameworkResources(); + + String currentLanguage = mLanguage.getText(); + + Set<String> set = null; + + if (projectResources != null) { + set = projectResources.getRegions(currentLanguage); + } + + if (frameworkResources != null) { + if (set != null) { + Set<String> set2 = frameworkResources.getRegions(currentLanguage); + set.addAll(set2); + } else { + set = frameworkResources.getRegions(currentLanguage); + } + } + + if (set != null) { + mDisableUpdates = true; + + mRegion.removeAll(); + for (String region : set) { + mRegion.add(region); + } + + mDisableUpdates = false; + } + } + + + /** + * Returns whether the given <var>style</var> is a theme. + * This is done by making sure the parent is a theme. + * @param value the style to check + * @param styleMap the map of styles for the current project. Key is the style name. + * @return True if the given <var>style</var> is a theme. + */ + 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) { + // if there is no specified parent style we look an implied one. + // For instance 'Theme.light' is implied child style of 'Theme', + // and 'Theme.light.fullscreen' is implied child style of 'Theme.light' + String name = style.getName(); + int index = name.lastIndexOf('.'); + if (index != -1) { + parentStyle = name.substring(0, index); + } + } else { + // remove the useless @ if it's there + 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()); + } + } + + if (frameworkStyle) { + // if the parent is a framework style, it has to be 'Theme' or 'Theme.*' + return parentStyle.equals("Theme") || parentStyle.startsWith("Theme."); + } else { + // if it's a project style, we check this is a theme. + value = styleMap.get(parentStyle); + if (value != null) { + return isTheme(value, styleMap); + } + } + } + + return false; + } + +} diff --git a/eclipse/plugins/com.android.ide.eclipse.common/.gitignore b/eclipse/plugins/com.android.ide.eclipse.common/.gitignore new file mode 100644 index 0000000..d392f0e --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.common/.gitignore @@ -0,0 +1 @@ +*.jar diff --git a/eclipse/plugins/com.android.ide.eclipse.ddms/META-INF/MANIFEST.MF b/eclipse/plugins/com.android.ide.eclipse.ddms/META-INF/MANIFEST.MF index 9f021ae..fd818bf 100644 --- a/eclipse/plugins/com.android.ide.eclipse.ddms/META-INF/MANIFEST.MF +++ b/eclipse/plugins/com.android.ide.eclipse.ddms/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Dalvik Debug Monitor Service Bundle-SymbolicName: com.android.ide.eclipse.ddms;singleton:=true -Bundle-Version: 0.9.3.qualifier +Bundle-Version: 0.9.4.qualifier Bundle-Activator: com.android.ide.eclipse.ddms.DdmsPlugin Bundle-Vendor: The Android Open Source Project Bundle-Localization: plugin diff --git a/eclipse/plugins/com.android.ide.eclipse.ddms/icons/.gitignore b/eclipse/plugins/com.android.ide.eclipse.ddms/icons/.gitignore new file mode 100644 index 0000000..f432e88 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.ddms/icons/.gitignore @@ -0,0 +1,31 @@ +add.png +backward.png +clear.png +d.png +debug-attach.png +debug-error.png +debug-wait.png +delete.png +device.png +down.png +e.png +edit.png +empty.png +emulator.png +forward.png +gc.png +halt.png +heap.png +i.png +importBug.png +load.png +pause.png +play.png +pull.png +push.png +save.png +thread.png +up.png +v.png +w.png +warning.png diff --git a/eclipse/plugins/com.android.ide.eclipse.ddms/libs/.gitignore b/eclipse/plugins/com.android.ide.eclipse.ddms/libs/.gitignore new file mode 100644 index 0000000..d392f0e --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.ddms/libs/.gitignore @@ -0,0 +1 @@ +*.jar diff --git a/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/.gitignore b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/.gitignore new file mode 100644 index 0000000..76d9981 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/.gitignore @@ -0,0 +1,2 @@ +ddmlib +ddmuilib diff --git a/eclipse/plugins/com.android.ide.eclipse.editors/.gitignore b/eclipse/plugins/com.android.ide.eclipse.editors/.gitignore new file mode 100644 index 0000000..d392f0e --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.editors/.gitignore @@ -0,0 +1 @@ +*.jar diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/.gitignore b/eclipse/plugins/com.android.ide.eclipse.tests/.gitignore new file mode 100644 index 0000000..d392f0e --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/.gitignore @@ -0,0 +1 @@ +*.jar diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/META-INF/MANIFEST.MF b/eclipse/plugins/com.android.ide.eclipse.tests/META-INF/MANIFEST.MF index a93bdef..61e8ee4 100644 --- a/eclipse/plugins/com.android.ide.eclipse.tests/META-INF/MANIFEST.MF +++ b/eclipse/plugins/com.android.ide.eclipse.tests/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Android Plugin Tests Bundle-SymbolicName: com.android.ide.eclipse.tests -Bundle-Version: 0.9.3.qualifier +Bundle-Version: 0.9.4.qualifier Bundle-Activator: com.android.ide.eclipse.tests.AndroidTestPlugin Require-Bundle: org.eclipse.ui, org.eclipse.core.runtime, diff --git a/eclipse/sites/external/site.xml b/eclipse/sites/external/site.xml index a00d1a4..ef0df64 100644 --- a/eclipse/sites/external/site.xml +++ b/eclipse/sites/external/site.xml @@ -3,10 +3,10 @@ <description url="https://dl-ssl.google.com/android/eclipse/"> Update Site for Android Development Toolkit </description> - <feature url="features/com.android.ide.eclipse.adt_0.9.3.qualifier.jar" id="com.android.ide.eclipse.adt" version="0.9.3.qualifier"> + <feature url="features/com.android.ide.eclipse.adt_0.9.4.qualifier.jar" id="com.android.ide.eclipse.adt" version="0.9.4.qualifier"> <category name="developer"/> </feature> - <feature url="features/com.android.ide.eclipse.ddms_0.9.3.qualifier.jar" id="com.android.ide.eclipse.ddms" version="0.9.3.qualifier"> + <feature url="features/com.android.ide.eclipse.ddms_0.9.4.qualifier.jar" id="com.android.ide.eclipse.ddms" version="0.9.4.qualifier"> <category name="developer"/> </feature> <category-def name="developer" label="Developer Tools"> diff --git a/eclipse/sites/internal/site.xml b/eclipse/sites/internal/site.xml index e19c119..31744d7 100644 --- a/eclipse/sites/internal/site.xml +++ b/eclipse/sites/internal/site.xml @@ -3,13 +3,13 @@ <description url="https://android.corp.google.com/adt/"> Update Site for Android Development Toolkit </description> - <feature url="features/com.android.ide.eclipse.adt_0.9.3.qualifier.jar" id="com.android.ide.eclipse.adt" version="0.9.3.qualifier"> + <feature url="features/com.android.ide.eclipse.adt_0.9.4.qualifier.jar" id="com.android.ide.eclipse.adt" version="0.9.4.qualifier"> <category name="developer"/> </feature> - <feature url="features/com.android.ide.eclipse.ddms_0.9.3.qualifier.jar" id="com.android.ide.eclipse.ddms" version="0.9.3.qualifier"> + <feature url="features/com.android.ide.eclipse.ddms_0.9.4.qualifier.jar" id="com.android.ide.eclipse.ddms" version="0.9.4.qualifier"> <category name="developer"/> </feature> - <feature url="features/com.android.ide.eclipse.tests_0.9.3.qualifier.jar" id="com.android.ide.eclipse.tests" version="0.9.3.qualifier"> + <feature url="features/com.android.ide.eclipse.tests_0.9.4.qualifier.jar" id="com.android.ide.eclipse.tests" version="0.9.4.qualifier"> <category name="test"/> </feature> <category-def name="developer" label="Application Developer Tools"> diff --git a/emulator/keymaps/AVRCP.kl b/emulator/keymaps/AVRCP.kl index d0eba10..aeb3c8a 100644 --- a/emulator/keymaps/AVRCP.kl +++ b/emulator/keymaps/AVRCP.kl @@ -1,6 +1,7 @@ -key 164 MEDIA_PLAY_PAUSE WAKE -key 128 MEDIA_STOP WAKE +key 200 MEDIA_PLAY_PAUSE WAKE +key 201 MEDIA_PLAY_PAUSE WAKE +key 166 MEDIA_STOP WAKE key 163 MEDIA_NEXT WAKE key 165 MEDIA_PREVIOUS WAKE key 168 MEDIA_REWIND WAKE -key 159 MEDIA_FAST_FORWARD WAKE +key 208 MEDIA_FAST_FORWARD WAKE diff --git a/emulator/qtools/dmtrace.cpp b/emulator/qtools/dmtrace.cpp index 6d9250a..c486c5f 100644 --- a/emulator/qtools/dmtrace.cpp +++ b/emulator/qtools/dmtrace.cpp @@ -5,6 +5,7 @@ #include <unistd.h> #include <inttypes.h> #include <string.h> +#include <unistd.h> #include "dmtrace.h" static const short kVersion = 2; @@ -163,7 +164,7 @@ void DmTrace::parseAndAddFunction(int functionId, const char *name) // sig = "()I" // Find the first parenthesis, the start of the signature. - char *paren = strchr(name, '('); + char *paren = (char*)strchr(name, '('); // If not found, then add the original name. if (paren == NULL) { @@ -180,7 +181,7 @@ void DmTrace::parseAndAddFunction(int functionId, const char *name) *paren = 0; // Search for the last period, the start of the method name - char *dot = strrchr(name, '.'); + char *dot = (char*)strrchr(name, '.'); // If not found, then add the original name. if (dot == NULL || dot == name) { diff --git a/emulator/qtools/trace_reader.cpp b/emulator/qtools/trace_reader.cpp index d2af64f..47b5d93 100644 --- a/emulator/qtools/trace_reader.cpp +++ b/emulator/qtools/trace_reader.cpp @@ -1009,10 +1009,10 @@ void TraceReaderBase::ParseDexList(const char *filename) // be freed by the caller after it is no longer needed. static char *ExtractDexPathFromMmap(const char *mmap_path) { - char *end = rindex(mmap_path, '@'); + const char *end = rindex(mmap_path, '@'); if (end == NULL) return NULL; - char *start = rindex(mmap_path, '/'); + const char *start = rindex(mmap_path, '/'); if (start == NULL) return NULL; int len = end - start; diff --git a/scripts/doc_source.properties b/scripts/doc_source.properties index 9382836..e6d6915 100644 --- a/scripts/doc_source.properties +++ b/scripts/doc_source.properties @@ -1,4 +1,6 @@ Pkg.UserSrc=false -Platform.Version=1.6 +Platform.Version=Eclair Pkg.Revision=1 AndroidVersion.ApiLevel=4 +AndroidVersion.CodeName=Eclair + diff --git a/scripts/platform_source.properties b/scripts/platform_source.properties index 49dc3ae..148c364 100644 --- a/scripts/platform_source.properties +++ b/scripts/platform_source.properties @@ -1,5 +1,6 @@ -Pkg.Desc=Android SDK Platform 1.6_r1 +Pkg.Desc=Android SDK Platform Eclair Pkg.UserSrc=false -Platform.Version=1.6 +Platform.Version=Eclair Pkg.Revision=1 AndroidVersion.ApiLevel=4 +AndroidVersion.CodeName=Eclair |