Utils.java revision 9138ce8a14924612c014da2b6e727b4117ba1a92
1146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project/*
2146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
3146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project *
4146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * you may not use this file except in compliance with the License.
6146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * You may obtain a copy of the License at
7146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project *
8146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project *
10146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * See the License for the specific language governing permissions and
14146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * limitations under the License.
15146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project */
16146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
17146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectpackage com.android.calendar;
18146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
19146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport static android.provider.Calendar.EVENT_BEGIN_TIME;
20e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan
21146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.content.Context;
22146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.content.Intent;
23e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chanimport android.content.SharedPreferences;
24ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chanimport android.database.Cursor;
25a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErikimport android.database.MatrixCursor;
26ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chanimport android.graphics.drawable.Drawable;
27ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chanimport android.graphics.drawable.GradientDrawable;
281ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erikimport android.net.Uri;
29eb10fa8bee049e0052b5cb53dcfbdaccef9f2740Erikimport android.text.TextUtils;
30146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.text.format.Time;
311ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erikimport android.util.Log;
32146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.view.animation.AlphaAnimation;
33146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.widget.ViewFlipper;
34146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
3556adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashiimport java.util.Calendar;
361ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erikimport java.util.List;
37ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chanimport java.util.Map;
3856adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi
39146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectpublic class Utils {
40bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    // Set to 0 until we have UI to perform undo
41bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    public static final long UNDO_DELAY = 0;
42bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
4379f228124de7d98146ca526d743436f6419e2365Erik    // For recurring events which instances of the series are being modified
4479f228124de7d98146ca526d743436f6419e2365Erik    public static final int MODIFY_UNINITIALIZED = 0;
4579f228124de7d98146ca526d743436f6419e2365Erik    public static final int MODIFY_SELECTED = 1;
4679f228124de7d98146ca526d743436f6419e2365Erik    public static final int MODIFY_ALL_FOLLOWING = 2;
4779f228124de7d98146ca526d743436f6419e2365Erik    public static final int MODIFY_ALL = 3;
4879f228124de7d98146ca526d743436f6419e2365Erik
4979f228124de7d98146ca526d743436f6419e2365Erik    // When the edit event view finishes it passes back the appropriate exit code.
5079f228124de7d98146ca526d743436f6419e2365Erik    public static final int DONE_REVERT = 0;
5179f228124de7d98146ca526d743436f6419e2365Erik    public static final int DONE_SAVE = 1;
5279f228124de7d98146ca526d743436f6419e2365Erik    public static final int DONE_DELETE = 2;
5379f228124de7d98146ca526d743436f6419e2365Erik
54ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan    private static final int CLEAR_ALPHA_MASK = 0x00FFFFFF;
55ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan    private static final int HIGH_ALPHA = 255 << 24;
56ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan    private static final int MED_ALPHA = 180 << 24;
57ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan    private static final int LOW_ALPHA = 150 << 24;
58ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan
59ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan    protected static final String OPEN_EMAIL_MARKER = " <";
60ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan    protected static final String CLOSE_EMAIL_MARKER = ">";
61ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan
62ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan    /* The corner should be rounded on the top right and bottom right */
63ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan    private static final float[] CORNERS = new float[] {0, 0, 5, 5, 5, 5, 0, 0};
64ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan
65ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan
66146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public static void startActivity(Context context, String className, long time) {
67146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        Intent intent = new Intent(Intent.ACTION_VIEW);
68146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
69146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        intent.setClassName(context, className);
70146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        intent.putExtra(EVENT_BEGIN_TIME, time);
7123f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan        intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP);
72146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
73146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        context.startActivity(intent);
74146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
75146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
7645efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan    static String getSharedPreference(Context context, String key, String defaultValue) {
77a17725e24d51b7a6f002dd5afd3270c8eeea0dbeJeff Hamilton        SharedPreferences prefs = CalendarPreferenceActivity.getSharedPreferences(context);
7845efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan        return prefs.getString(key, defaultValue);
7945efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan    }
8045efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan
8145efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan    static void setSharedPreference(Context context, String key, String value) {
82a17725e24d51b7a6f002dd5afd3270c8eeea0dbeJeff Hamilton        SharedPreferences prefs = CalendarPreferenceActivity.getSharedPreferences(context);
8345efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan        SharedPreferences.Editor editor = prefs.edit();
8445efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan        editor.putString(key, value);
8545efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan        editor.commit();
8645efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan    }
8745efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan
88e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan    static void setDefaultView(Context context, int viewId) {
89e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan        String activityString = CalendarApplication.ACTIVITY_NAMES[viewId];
90e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan
91a17725e24d51b7a6f002dd5afd3270c8eeea0dbeJeff Hamilton        SharedPreferences prefs = CalendarPreferenceActivity.getSharedPreferences(context);
92e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan        SharedPreferences.Editor editor = prefs.edit();
93e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan        if (viewId == CalendarApplication.AGENDA_VIEW_ID ||
94e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan                viewId == CalendarApplication.DAY_VIEW_ID) {
95e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan            // Record the (new) detail start view only for Agenda and Day
96e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan            editor.putString(CalendarPreferenceActivity.KEY_DETAILED_VIEW, activityString);
97e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan        }
98e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan
99e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan        // Record the (new) start view
100e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan        editor.putString(CalendarPreferenceActivity.KEY_START_VIEW, activityString);
101e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan        editor.commit();
102e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan    }
103e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan
104146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public static final Time timeFromIntent(Intent intent) {
105146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        Time time = new Time();
106146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        time.set(timeFromIntentInMillis(intent));
107146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        return time;
108146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
109146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
110a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik    public static MatrixCursor matrixCursorFromCursor(Cursor cursor) {
111a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik        MatrixCursor newCursor = new MatrixCursor(cursor.getColumnNames());
112a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik        int numColumns = cursor.getColumnCount();
113a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik        String data[] = new String[numColumns];
114a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik        cursor.moveToPosition(-1);
115a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik        while (cursor.moveToNext()) {
116a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik            for (int i = 0; i < numColumns; i++) {
117a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik                data[i] = cursor.getString(i);
118a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik            }
119a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik            newCursor.addRow(data);
120a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik        }
121a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik        return newCursor;
122a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik    }
123a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik
124a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik    /**
125a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik     * Compares two cursors to see if they contain the same data.
126a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik     *
127a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik     * @return Returns true of the cursors contain the same data and are not null, false
128a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik     * otherwise
129a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik     */
130a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik    public static boolean compareCursors(Cursor c1, Cursor c2) {
131a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik        if(c1 == null || c2 == null) {
132a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik            return false;
133a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik        }
134a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik
135a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik        int numColumns = c1.getColumnCount();
136a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik        if (numColumns != c2.getColumnCount()) {
137a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik            return false;
138a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik        }
139a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik
140a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik        if (c1.getCount() != c2.getCount()) {
141a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik            return false;
142a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik        }
143a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik
144a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik        c1.moveToPosition(-1);
145a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik        c2.moveToPosition(-1);
146a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik        while(c1.moveToNext() && c2.moveToNext()) {
147a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik            for(int i = 0; i < numColumns; i++) {
148eb10fa8bee049e0052b5cb53dcfbdaccef9f2740Erik                if(!TextUtils.equals(c1.getString(i), c2.getString(i))) {
149a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik                    return false;
150a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik                }
151a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik            }
152a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik        }
153a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik
154a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik        return true;
155a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik    }
156a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik
157146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    /**
158146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * If the given intent specifies a time (in milliseconds since the epoch),
159146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * then that time is returned. Otherwise, the current time is returned.
160146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     */
161146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public static final long timeFromIntentInMillis(Intent intent) {
162146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        // If the time was specified, then use that.  Otherwise, use the current time.
1631ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik        Uri data = intent.getData();
164146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        long millis = intent.getLongExtra(EVENT_BEGIN_TIME, -1);
1651ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik        if (millis == -1 && data != null && data.isHierarchical()) {
1661ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik            List<String> path = data.getPathSegments();
167eca5d33e4230cf6ac3acfe3fabf853f9275f98caErik            if(path.size() == 2 && path.get(0).equals("time")) {
1681ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik                try {
1691ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik                    millis = Long.valueOf(data.getLastPathSegment());
1701ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik                } catch (NumberFormatException e) {
1711ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik                    Log.i("Calendar", "timeFromIntentInMillis: Data existed but no valid time " +
1721ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik                            "found. Using current time.");
1731ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik                }
1741ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik            }
1751ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik        }
17676727b7a9cf780f200414548b9d454bf9a701e3eErik        if (millis <= 0) {
177146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            millis = System.currentTimeMillis();
178146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
179146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        return millis;
180146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
181146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
182146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public static final void applyAlphaAnimation(ViewFlipper v) {
183146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        AlphaAnimation in = new AlphaAnimation(0.0f, 1.0f);
184146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
185146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        in.setStartOffset(0);
186146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        in.setDuration(500);
187146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
188146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        AlphaAnimation out = new AlphaAnimation(1.0f, 0.0f);
189146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
190146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        out.setStartOffset(0);
191146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        out.setDuration(500);
192146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
193146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        v.setInAnimation(in);
194146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        v.setOutAnimation(out);
195146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
196146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
197ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan    public static Drawable getColorChip(int color) {
198ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan        /*
199ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan         * We want the color chip to have a nice gradient using
200ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan         * the color of the calendar. To do this we use a GradientDrawable.
201ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan         * The color supplied has an alpha of FF so we first do:
202ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan         * color & 0x00FFFFFF
203ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan         * to clear the alpha. Then we add our alpha to it.
204ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan         * We use 3 colors to get a step effect where it starts off very
205ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan         * light and quickly becomes dark and then a slow transition to
206ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan         * be even darker.
207ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan         */
208ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan        color &= CLEAR_ALPHA_MASK;
209ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan        int startColor = color | HIGH_ALPHA;
210ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan        int middleColor = color | MED_ALPHA;
211ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan        int endColor = color | LOW_ALPHA;
212ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan        int[] colors = new int[] {startColor, middleColor, endColor};
213ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan        GradientDrawable d = new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT, colors);
214ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan        d.setCornerRadii(CORNERS);
215ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan        return d;
216ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan    }
217ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan
218146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    /**
219146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * Formats the given Time object so that it gives the month and year
220146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * (for example, "September 2007").
221146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     *
222146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * @param time the time to format
223146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * @return the string containing the weekday and the date
224146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     */
225ad36a3c3cde7a2ec6d3a35d2529d46f03bd8d59dMichael Chan    public static String formatMonthYear(Context context, Time time) {
226ad36a3c3cde7a2ec6d3a35d2529d46f03bd8d59dMichael Chan        return time.format(context.getResources().getString(R.string.month_year));
227146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
228146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
229146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    /**
230146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * Sets the time to the beginning of the day (midnight) by clearing the
231146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * hour, minute, and second fields.
232146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     */
233146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    static void setTimeToStartOfDay(Time time) {
234146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        time.second = 0;
235146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        time.minute = 0;
236146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        time.hour = 0;
237146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
23856adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi
23956adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi    /**
24056adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi     * Get first day of week as android.text.format.Time constant.
24156adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi     * @return the first day of week in android.text.format.Time
24256adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi     */
2438e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang    public static int getFirstDayOfWeek(Context context) {
2448e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang        SharedPreferences prefs = CalendarPreferenceActivity.getSharedPreferences(context);
2458e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang        String pref = prefs.getString(
2468e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang                CalendarPreferenceActivity.KEY_WEEK_START_DAY,
2478e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang                CalendarPreferenceActivity.WEEK_START_DEFAULT);
2488e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang
2498e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang        int startDay;
2508e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang        if (CalendarPreferenceActivity.WEEK_START_DEFAULT.equals(pref)) {
2518e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang            startDay = Calendar.getInstance().getFirstDayOfWeek();
2528e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang        } else {
2538e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang            startDay = Integer.parseInt(pref);
2548e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang        }
2558e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang
25656adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi        if (startDay == Calendar.SATURDAY) {
25756adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi            return Time.SATURDAY;
25856adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi        } else if (startDay == Calendar.MONDAY) {
25956adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi            return Time.MONDAY;
26056adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi        } else {
26156adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi            return Time.SUNDAY;
26256adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi        }
26356adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi    }
26456adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi
26556adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi    /**
26656adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi     * Determine whether the column position is Saturday or not.
26756adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi     * @param column the column position
26856adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi     * @param firstDayOfWeek the first day of week in android.text.format.Time
26956adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi     * @return true if the column is Saturday position
27056adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi     */
27156adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi    public static boolean isSaturday(int column, int firstDayOfWeek) {
27256adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi        return (firstDayOfWeek == Time.SUNDAY && column == 6)
27356adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi            || (firstDayOfWeek == Time.MONDAY && column == 5)
27456adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi            || (firstDayOfWeek == Time.SATURDAY && column == 0);
27556adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi    }
27656adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi
27756adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi    /**
27856adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi     * Determine whether the column position is Sunday or not.
27956adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi     * @param column the column position
28056adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi     * @param firstDayOfWeek the first day of week in android.text.format.Time
28156adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi     * @return true if the column is Sunday position
28256adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi     */
28356adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi    public static boolean isSunday(int column, int firstDayOfWeek) {
28456adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi        return (firstDayOfWeek == Time.SUNDAY && column == 0)
28556adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi            || (firstDayOfWeek == Time.MONDAY && column == 6)
28656adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi            || (firstDayOfWeek == Time.SATURDAY && column == 1);
28756adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi    }
288ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan
289ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan    /**
290ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan     * Scan through a cursor of calendars and check if names are duplicated.
291ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan     *
292ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan     * This travels a cursor containing calendar display names and fills in the provided map with
293ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan     * whether or not each name is repeated.
294ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan     * @param isDuplicateName The map to put the duplicate check results in.
295ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan     * @param cursor The query of calendars to check
296ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan     * @param nameIndex The column of the query that contains the display name
297ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan     */
298ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan    public static void checkForDuplicateNames(Map<String, Boolean> isDuplicateName, Cursor cursor,
299ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan            int nameIndex) {
300ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan        isDuplicateName.clear();
301ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan        cursor.moveToPosition(-1);
302ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan        while (cursor.moveToNext()) {
303ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan            String displayName = cursor.getString(nameIndex);
304ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan            // Set it to true if we've seen this name before, false otherwise
305ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan            if (displayName != null) {
306ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan                isDuplicateName.put(displayName, isDuplicateName.containsKey(displayName));
307ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan            }
308ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan        }
309ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan    }
3109138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang
3119138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang    /**
3129138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang     * Null-safe object comparison
3139138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang     * @param s1
3149138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang     * @param s2
3159138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang     * @return
3169138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang     */
3179138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang    public static boolean equals(Object o1, Object o2) {
3189138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang        return o1 == null ? o2 == null : o1.equals(o2);
3199138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang    }
320146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project}
321