diff options
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/NestedConfiguration.java')
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/NestedConfiguration.java | 506 |
1 files changed, 506 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/NestedConfiguration.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/NestedConfiguration.java new file mode 100644 index 0000000..50778e2 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/NestedConfiguration.java @@ -0,0 +1,506 @@ +/* + * Copyright (C) 2012 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.annotations.NonNull; +import com.android.annotations.Nullable; +import com.android.ide.common.resources.configuration.FolderConfiguration; +import com.android.resources.NightMode; +import com.android.resources.UiMode; +import com.android.sdklib.IAndroidTarget; +import com.android.sdklib.devices.Device; +import com.android.sdklib.devices.State; +import com.google.common.base.Objects; + +/** + * An {@linkplain NestedConfiguration} is a {@link Configuration} which inherits + * all of its values from a different configuration, except for one or more + * attributes where it overrides a custom value. + * <p> + * Unlike a {@link VaryingConfiguration}, a {@linkplain NestedConfiguration} + * will always return the same overridden value, regardless of the inherited + * value. + * <p> + * For example, an {@linkplain NestedConfiguration} may fix the locale to always + * be "en", but otherwise inherit everything else. + */ +public class NestedConfiguration extends Configuration { + /** The configuration we are inheriting non-overridden values from */ + protected Configuration mParent; + + /** Bitmask of attributes to be overridden in this configuration */ + private int mOverride; + + /** + * Constructs a new {@linkplain NestedConfiguration}. + * Construct via + * + * @param chooser the associated chooser + * @param configuration the configuration to inherit from + */ + protected NestedConfiguration( + @NonNull ConfigurationChooser chooser, + @NonNull Configuration configuration) { + super(chooser); + mParent = configuration; + + mFullConfig.set(mParent.mFullConfig); + if (mParent.getEditedConfig() != null) { + mEditedConfig = new FolderConfiguration(); + mEditedConfig.set(mParent.mEditedConfig); + } + } + + /** + * Returns the override flags for this configuration. Corresponds to + * the {@code CFG_} flags in {@link ConfigurationClient}. + * + * @return the bitmask + */ + public int getOverrideFlags() { + return mOverride; + } + + /** + * Creates a new {@linkplain NestedConfiguration} that has the same overriding + * attributes as the given other {@linkplain NestedConfiguration}, and gets + * its values from the given {@linkplain Configuration}. + * + * @param other the configuration to copy overrides from + * @param values the configuration to copy values from + * @param parent the parent to tie the configuration to for inheriting values + * @return a new configuration + */ + @NonNull + public static NestedConfiguration create( + @NonNull NestedConfiguration other, + @NonNull Configuration values, + @NonNull Configuration parent) { + NestedConfiguration configuration = + new NestedConfiguration(other.mConfigChooser, parent); + initFrom(configuration, other, values, true /*sync*/); + return configuration; + } + + /** + * Initializes a new {@linkplain NestedConfiguration} with the overriding + * attributes as the given other {@linkplain NestedConfiguration}, and gets + * its values from the given {@linkplain Configuration}. + * + * @param configuration the configuration to initialize + * @param other the configuration to copy overrides from + * @param values the configuration to copy values from + * @param sync if true, sync the folder configuration from + */ + protected static void initFrom(NestedConfiguration configuration, + NestedConfiguration other, Configuration values, boolean sync) { + configuration.mOverride = other.mOverride; + configuration.setDisplayName(values.getDisplayName()); + configuration.setActivity(values.getActivity()); + + if (configuration.isOverridingLocale()) { + configuration.setLocale(values.getLocale(), true); + } + if (configuration.isOverridingTarget()) { + configuration.setTarget(values.getTarget(), true); + } + if (configuration.isOverridingDevice()) { + configuration.setDevice(values.getDevice(), true); + } + if (configuration.isOverridingDeviceState()) { + configuration.setDeviceState(values.getDeviceState(), true); + } + if (configuration.isOverridingNightMode()) { + configuration.setNightMode(values.getNightMode(), true); + } + if (configuration.isOverridingUiMode()) { + configuration.setUiMode(values.getUiMode(), true); + } + if (sync) { + configuration.syncFolderConfig(); + } + } + + /** + * Sets the parent configuration that this configuration is inheriting from. + * + * @param parent the parent configuration + */ + public void setParent(@NonNull Configuration parent) { + mParent = parent; + } + + /** + * Creates a new {@linkplain Configuration} which inherits values from the + * given parent {@linkplain Configuration}, possibly overriding some as + * well. + * + * @param chooser the associated chooser + * @param parent the configuration to inherit values from + * @return a new configuration + */ + @NonNull + public static NestedConfiguration create(@NonNull ConfigurationChooser chooser, + @NonNull Configuration parent) { + return new NestedConfiguration(chooser, parent); + } + + @Override + @Nullable + public String getTheme() { + // Never overridden: this is a static attribute of a layout, not something which + // varies by configuration or at runtime + return mParent.getTheme(); + } + + @Override + public void setTheme(String theme) { + // Never overridden + mParent.setTheme(theme); + } + + /** + * Sets whether the locale should be overridden by this configuration + * + * @param override if true, override the inherited value + */ + public void setOverrideLocale(boolean override) { + mOverride |= CFG_LOCALE; + } + + /** + * Returns true if the locale is overridden + * + * @return true if the locale is overridden + */ + public final boolean isOverridingLocale() { + return (mOverride & CFG_LOCALE) != 0; + } + + @Override + @NonNull + public Locale getLocale() { + if (isOverridingLocale()) { + return super.getLocale(); + } else { + return mParent.getLocale(); + } + } + + @Override + public void setLocale(@NonNull Locale locale, boolean skipSync) { + if (isOverridingLocale()) { + super.setLocale(locale, skipSync); + } else { + mParent.setLocale(locale, skipSync); + } + } + + /** + * Sets whether the rendering target should be overridden by this configuration + * + * @param override if true, override the inherited value + */ + public void setOverrideTarget(boolean override) { + mOverride |= CFG_TARGET; + } + + /** + * Returns true if the target is overridden + * + * @return true if the target is overridden + */ + public final boolean isOverridingTarget() { + return (mOverride & CFG_TARGET) != 0; + } + + @Override + @Nullable + public IAndroidTarget getTarget() { + if (isOverridingTarget()) { + return super.getTarget(); + } else { + return mParent.getTarget(); + } + } + + @Override + public void setTarget(IAndroidTarget target, boolean skipSync) { + if (isOverridingTarget()) { + super.setTarget(target, skipSync); + } else { + mParent.setTarget(target, skipSync); + } + } + + /** + * Sets whether the device should be overridden by this configuration + * + * @param override if true, override the inherited value + */ + public void setOverrideDevice(boolean override) { + mOverride |= CFG_DEVICE; + } + + /** + * Returns true if the device is overridden + * + * @return true if the device is overridden + */ + public final boolean isOverridingDevice() { + return (mOverride & CFG_DEVICE) != 0; + } + + @Override + @Nullable + public Device getDevice() { + if (isOverridingDevice()) { + return super.getDevice(); + } else { + return mParent.getDevice(); + } + } + + @Override + public void setDevice(Device device, boolean skipSync) { + if (isOverridingDevice()) { + super.setDevice(device, skipSync); + } else { + mParent.setDevice(device, skipSync); + } + } + + /** + * Sets whether the device state should be overridden by this configuration + * + * @param override if true, override the inherited value + */ + public void setOverrideDeviceState(boolean override) { + mOverride |= CFG_DEVICE_STATE; + } + + /** + * Returns true if the device state is overridden + * + * @return true if the device state is overridden + */ + public final boolean isOverridingDeviceState() { + return (mOverride & CFG_DEVICE_STATE) != 0; + } + + @Override + @Nullable + public State getDeviceState() { + if (isOverridingDeviceState()) { + return super.getDeviceState(); + } else { + State state = mParent.getDeviceState(); + if (isOverridingDevice()) { + // If the device differs, I need to look up a suitable equivalent state + // on our device + if (state != null) { + Device device = super.getDevice(); + if (device != null) { + return device.getState(state.getName()); + } + } + } + + return state; + } + } + + @Override + public void setDeviceState(State state, boolean skipSync) { + if (isOverridingDeviceState()) { + super.setDeviceState(state, skipSync); + } else { + if (isOverridingDevice()) { + Device device = super.getDevice(); + if (device != null) { + State equivalentState = device.getState(state.getName()); + if (equivalentState != null) { + state = equivalentState; + } + } + } + mParent.setDeviceState(state, skipSync); + } + } + + /** + * Sets whether the night mode should be overridden by this configuration + * + * @param override if true, override the inherited value + */ + public void setOverrideNightMode(boolean override) { + mOverride |= CFG_NIGHT_MODE; + } + + /** + * Returns true if the night mode is overridden + * + * @return true if the night mode is overridden + */ + public final boolean isOverridingNightMode() { + return (mOverride & CFG_NIGHT_MODE) != 0; + } + + @Override + @NonNull + public NightMode getNightMode() { + if (isOverridingNightMode()) { + return super.getNightMode(); + } else { + return mParent.getNightMode(); + } + } + + @Override + public void setNightMode(@NonNull NightMode night, boolean skipSync) { + if (isOverridingNightMode()) { + super.setNightMode(night, skipSync); + } else { + mParent.setNightMode(night, skipSync); + } + } + + /** + * Sets whether the UI mode should be overridden by this configuration + * + * @param override if true, override the inherited value + */ + public void setOverrideUiMode(boolean override) { + mOverride |= CFG_UI_MODE; + } + + /** + * Returns true if the UI mode is overridden + * + * @return true if the UI mode is overridden + */ + public final boolean isOverridingUiMode() { + return (mOverride & CFG_UI_MODE) != 0; + } + + @Override + @NonNull + public UiMode getUiMode() { + if (isOverridingUiMode()) { + return super.getUiMode(); + } else { + return mParent.getUiMode(); + } + } + + @Override + public void setUiMode(@NonNull UiMode uiMode, boolean skipSync) { + if (isOverridingUiMode()) { + super.setUiMode(uiMode, skipSync); + } else { + mParent.setUiMode(uiMode, skipSync); + } + } + + /** + * Returns the configuration this {@linkplain NestedConfiguration} is + * inheriting from + * + * @return the configuration this configuration is inheriting from + */ + @NonNull + public Configuration getParent() { + return mParent; + } + + @Override + @Nullable + public String getActivity() { + return mParent.getActivity(); + } + + @Override + public void setActivity(String activity) { + super.setActivity(activity); + } + + /** + * Returns a computed display name (ignoring the value stored by + * {@link #setDisplayName(String)}) by looking at the override flags + * and picking a suitable name. + * + * @return a suitable display name + */ + @Nullable + public String computeDisplayName() { + return computeDisplayName(mOverride, this); + } + + /** + * Computes a display name for the given configuration, using the given + * override flags (which correspond to the {@code CFG_} constants in + * {@link ConfigurationClient} + * + * @param flags the override bitmask + * @param configuration the configuration to fetch values from + * @return a suitable display name + */ + @Nullable + public static String computeDisplayName(int flags, @NonNull Configuration configuration) { + if ((flags & CFG_LOCALE) != 0) { + return ConfigurationChooser.getLocaleLabel(configuration.mConfigChooser, + configuration.getLocale(), false); + } + + if ((flags & CFG_TARGET) != 0) { + return ConfigurationChooser.getRenderingTargetLabel(configuration.getTarget(), false); + } + + if ((flags & CFG_DEVICE) != 0) { + return ConfigurationChooser.getDeviceLabel(configuration.getDevice(), true); + } + + if ((flags & CFG_DEVICE_STATE) != 0) { + State deviceState = configuration.getDeviceState(); + if (deviceState != null) { + return deviceState.getName(); + } + } + + if ((flags & CFG_NIGHT_MODE) != 0) { + return configuration.getNightMode().getLongDisplayValue(); + } + + if ((flags & CFG_UI_MODE) != 0) { + configuration.getUiMode().getLongDisplayValue(); + } + + return null; + } + + @Override + public String toString() { + return Objects.toStringHelper(this.getClass()) + .add("parent", mParent.getDisplayName()) //$NON-NLS-1$ + .add("display", getDisplayName()) //$NON-NLS-1$ + .add("overrideLocale", isOverridingLocale()) //$NON-NLS-1$ + .add("overrideTarget", isOverridingTarget()) //$NON-NLS-1$ + .add("overrideDevice", isOverridingDevice()) //$NON-NLS-1$ + .add("overrideDeviceState", isOverridingDeviceState()) //$NON-NLS-1$ + .add("persistent", toPersistentString()) //$NON-NLS-1$ + .toString(); + } +} |