aboutsummaryrefslogtreecommitdiff
path: root/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/NestedConfiguration.java
diff options
context:
space:
mode:
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.java506
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 000000000..50778e2f1
--- /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();
+ }
+}