All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.holoeverywhere.preference.PreferenceInflater Maven / Gradle / Ivy

The newest version!

package org.holoeverywhere.preference;

import java.io.IOException;

import org.holoeverywhere.internal.GenericInflater;
import org.holoeverywhere.util.XmlUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.net.Uri;
import android.os.Bundle;
import android.util.AttributeSet;
import android.util.TypedValue;

public class PreferenceInflater extends GenericInflater {
    private static final String EXTRA_TAG_NAME = "extra";
    private static final String INTENT_TAG_NAME = "intent";

    private static void parseBundleExtra(Resources resources, String tagName, AttributeSet attrs,
            Bundle outBundle) throws XmlPullParserException {
        TypedArray sa = resources.obtainAttributes(attrs, R.styleable.Extra);
        String name = sa.getString(R.styleable.Extra_name);
        if (name == null) {
            sa.recycle();
            throw new XmlPullParserException("<" + tagName
                    + "> requires an holo:name attribute at "
                    + attrs.getPositionDescription());
        }
        TypedValue v = sa.peekValue(R.styleable.Extra_value);
        if (v != null) {
            if (v.type == TypedValue.TYPE_STRING) {
                CharSequence cs = v.coerceToString();
                outBundle.putCharSequence(name, cs);
            } else if (v.type == TypedValue.TYPE_INT_BOOLEAN) {
                outBundle.putBoolean(name, v.data != 0);
            } else if (v.type >= TypedValue.TYPE_FIRST_INT
                    && v.type <= TypedValue.TYPE_LAST_INT) {
                outBundle.putInt(name, v.data);
            } else if (v.type == TypedValue.TYPE_FLOAT) {
                outBundle.putFloat(name, v.getFloat());
            } else {
                sa.recycle();
                throw new XmlPullParserException("<" + tagName
                        + "> only supports string, integer, float, color, and boolean at "
                        + attrs.getPositionDescription());
            }
        } else {
            sa.recycle();
            throw new XmlPullParserException("<" + tagName
                    + "> requires an holo:value attribute at " + attrs.getPositionDescription());
        }
        sa.recycle();
    }

    private static Intent parseIntent(Resources resources, XmlPullParser parser, AttributeSet attrs)
            throws XmlPullParserException, IOException {
        Intent intent = new Intent();
        TypedArray sa = resources.obtainAttributes(attrs,
                R.styleable.Intent);
        intent.setAction(sa.getString(R.styleable.Intent_action));
        String data = sa.getString(R.styleable.Intent_data);
        String mimeType = sa.getString(R.styleable.Intent_mimeType);
        intent.setDataAndType(data != null ? Uri.parse(data) : null, mimeType);
        String packageName = sa.getString(R.styleable.Intent_targetPackage);
        String className = sa.getString(R.styleable.Intent_targetClass);
        if (packageName != null && className != null) {
            intent.setComponent(new ComponentName(packageName, className));
        }
        sa.recycle();
        int outerDepth = parser.getDepth();
        int type;
        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
                continue;
            }
            String nodeName = parser.getName();
            if (nodeName.equals("category")) {
                sa = resources.obtainAttributes(attrs, R.styleable.IntentCategory);
                String cat = sa.getString(R.styleable.IntentCategory_name);
                sa.recycle();
                if (cat != null) {
                    intent.addCategory(cat);
                }
                XmlUtils.skipCurrentTag(parser);
            } else if (nodeName.equals("extra")) {
                Bundle bundle = new Bundle();
                parseBundleExtra(resources,
                        "extra", attrs, bundle);
                intent.putExtras(bundle);
                XmlUtils.skipCurrentTag(parser);
            } else {
                XmlUtils.skipCurrentTag(parser);
            }
        }
        return intent;
    }

    private PreferenceManager mPreferenceManager;

    public PreferenceInflater(Context context, PreferenceManager preferenceManager) {
        super(PreferenceInit.context(context));
        init(preferenceManager);
    }

    public PreferenceInflater(PreferenceInflater original,
            PreferenceManager preferenceManager, Context newContext) {
        super(original, PreferenceInit.context(newContext));
        init(preferenceManager);
    }

    @Override
    public PreferenceInflater cloneInContext(Context newContext) {
        return new PreferenceInflater(this, mPreferenceManager, newContext);
    }

    private void init(PreferenceManager preferenceManager) {
        mPreferenceManager = preferenceManager;
        registerPackage(PreferenceInit.PACKAGE);
    }

    @Override
    protected boolean onCreateCustomFromTag(XmlPullParser parser,
            Preference parentPreference, AttributeSet attrs)
            throws XmlPullParserException {
        final String tag = parser.getName();
        if (tag.equals(PreferenceInflater.INTENT_TAG_NAME)) {
            Intent intent = null;
            try {
                intent = parseIntent(getContext().getResources(), parser, attrs);
            } catch (IOException e) {
                XmlPullParserException ex = new XmlPullParserException(
                        "Error parsing preference");
                ex.initCause(e);
                throw ex;
            }
            if (intent != null) {
                parentPreference.setIntent(intent);
            }

            return true;
        } else if (tag.equals(PreferenceInflater.EXTRA_TAG_NAME)) {
            parseBundleExtra(getContext().getResources(),
                    PreferenceInflater.EXTRA_TAG_NAME, attrs,
                    parentPreference.getExtras());
            try {
                XmlUtils.skipCurrentTag(parser);
            } catch (IOException e) {
                XmlPullParserException ex = new XmlPullParserException(
                        "Error parsing preference");
                ex.initCause(e);
                throw ex;
            }
            return true;
        }

        return false;
    }

    @Override
    protected PreferenceGroup onMergeRoots(PreferenceGroup givenRoot,
            boolean attachToGivenRoot, PreferenceGroup xmlRoot) {
        if (givenRoot == null) {
            xmlRoot.onAttachedToHierarchy(mPreferenceManager);
            return xmlRoot;
        } else {
            return givenRoot;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy