Utils.java revision 79f228124de7d98146ca526d743436f6419e2365
1/* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.calendar; 18 19import static android.provider.Calendar.EVENT_BEGIN_TIME; 20 21import android.content.Context; 22import android.content.Intent; 23import android.content.SharedPreferences; 24import android.database.Cursor; 25import android.database.MatrixCursor; 26import android.graphics.drawable.Drawable; 27import android.graphics.drawable.GradientDrawable; 28import android.net.Uri; 29import android.text.TextUtils; 30import android.text.format.Time; 31import android.util.Log; 32import android.view.animation.AlphaAnimation; 33import android.widget.ViewFlipper; 34 35import java.util.Calendar; 36import java.util.List; 37import java.util.Map; 38 39public class Utils { 40 // Set to 0 until we have UI to perform undo 41 public static final long UNDO_DELAY = 0; 42 43 // For recurring events which instances of the series are being modified 44 public static final int MODIFY_UNINITIALIZED = 0; 45 public static final int MODIFY_SELECTED = 1; 46 public static final int MODIFY_ALL_FOLLOWING = 2; 47 public static final int MODIFY_ALL = 3; 48 49 // When the edit event view finishes it passes back the appropriate exit code. 50 public static final int DONE_REVERT = 0; 51 public static final int DONE_SAVE = 1; 52 public static final int DONE_DELETE = 2; 53 54 private static final int CLEAR_ALPHA_MASK = 0x00FFFFFF; 55 private static final int HIGH_ALPHA = 255 << 24; 56 private static final int MED_ALPHA = 180 << 24; 57 private static final int LOW_ALPHA = 150 << 24; 58 59 protected static final String OPEN_EMAIL_MARKER = " <"; 60 protected static final String CLOSE_EMAIL_MARKER = ">"; 61 62 /* The corner should be rounded on the top right and bottom right */ 63 private static final float[] CORNERS = new float[] {0, 0, 5, 5, 5, 5, 0, 0}; 64 65 66 public static void startActivity(Context context, String className, long time) { 67 Intent intent = new Intent(Intent.ACTION_VIEW); 68 69 intent.setClassName(context, className); 70 intent.putExtra(EVENT_BEGIN_TIME, time); 71 intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP); 72 73 context.startActivity(intent); 74 } 75 76 static String getSharedPreference(Context context, String key, String defaultValue) { 77 SharedPreferences prefs = CalendarPreferenceActivity.getSharedPreferences(context); 78 return prefs.getString(key, defaultValue); 79 } 80 81 static void setSharedPreference(Context context, String key, String value) { 82 SharedPreferences prefs = CalendarPreferenceActivity.getSharedPreferences(context); 83 SharedPreferences.Editor editor = prefs.edit(); 84 editor.putString(key, value); 85 editor.commit(); 86 } 87 88 static void setDefaultView(Context context, int viewId) { 89 String activityString = CalendarApplication.ACTIVITY_NAMES[viewId]; 90 91 SharedPreferences prefs = CalendarPreferenceActivity.getSharedPreferences(context); 92 SharedPreferences.Editor editor = prefs.edit(); 93 if (viewId == CalendarApplication.AGENDA_VIEW_ID || 94 viewId == CalendarApplication.DAY_VIEW_ID) { 95 // Record the (new) detail start view only for Agenda and Day 96 editor.putString(CalendarPreferenceActivity.KEY_DETAILED_VIEW, activityString); 97 } 98 99 // Record the (new) start view 100 editor.putString(CalendarPreferenceActivity.KEY_START_VIEW, activityString); 101 editor.commit(); 102 } 103 104 public static final Time timeFromIntent(Intent intent) { 105 Time time = new Time(); 106 time.set(timeFromIntentInMillis(intent)); 107 return time; 108 } 109 110 public static MatrixCursor matrixCursorFromCursor(Cursor cursor) { 111 MatrixCursor newCursor = new MatrixCursor(cursor.getColumnNames()); 112 int numColumns = cursor.getColumnCount(); 113 String data[] = new String[numColumns]; 114 cursor.moveToPosition(-1); 115 while (cursor.moveToNext()) { 116 for (int i = 0; i < numColumns; i++) { 117 data[i] = cursor.getString(i); 118 } 119 newCursor.addRow(data); 120 } 121 return newCursor; 122 } 123 124 /** 125 * Compares two cursors to see if they contain the same data. 126 * 127 * @return Returns true of the cursors contain the same data and are not null, false 128 * otherwise 129 */ 130 public static boolean compareCursors(Cursor c1, Cursor c2) { 131 if(c1 == null || c2 == null) { 132 return false; 133 } 134 135 int numColumns = c1.getColumnCount(); 136 if (numColumns != c2.getColumnCount()) { 137 return false; 138 } 139 140 if (c1.getCount() != c2.getCount()) { 141 return false; 142 } 143 144 c1.moveToPosition(-1); 145 c2.moveToPosition(-1); 146 while(c1.moveToNext() && c2.moveToNext()) { 147 for(int i = 0; i < numColumns; i++) { 148 if(!TextUtils.equals(c1.getString(i), c2.getString(i))) { 149 return false; 150 } 151 } 152 } 153 154 return true; 155 } 156 157 /** 158 * If the given intent specifies a time (in milliseconds since the epoch), 159 * then that time is returned. Otherwise, the current time is returned. 160 */ 161 public static final long timeFromIntentInMillis(Intent intent) { 162 // If the time was specified, then use that. Otherwise, use the current time. 163 Uri data = intent.getData(); 164 long millis = intent.getLongExtra(EVENT_BEGIN_TIME, -1); 165 if (millis == -1 && data != null && data.isHierarchical()) { 166 List<String> path = data.getPathSegments(); 167 if(path.size() == 2 && path.get(0).equals("time")) { 168 try { 169 millis = Long.valueOf(data.getLastPathSegment()); 170 } catch (NumberFormatException e) { 171 Log.i("Calendar", "timeFromIntentInMillis: Data existed but no valid time " + 172 "found. Using current time."); 173 } 174 } 175 } 176 if (millis <= 0) { 177 millis = System.currentTimeMillis(); 178 } 179 return millis; 180 } 181 182 public static final void applyAlphaAnimation(ViewFlipper v) { 183 AlphaAnimation in = new AlphaAnimation(0.0f, 1.0f); 184 185 in.setStartOffset(0); 186 in.setDuration(500); 187 188 AlphaAnimation out = new AlphaAnimation(1.0f, 0.0f); 189 190 out.setStartOffset(0); 191 out.setDuration(500); 192 193 v.setInAnimation(in); 194 v.setOutAnimation(out); 195 } 196 197 public static Drawable getColorChip(int color) { 198 /* 199 * We want the color chip to have a nice gradient using 200 * the color of the calendar. To do this we use a GradientDrawable. 201 * The color supplied has an alpha of FF so we first do: 202 * color & 0x00FFFFFF 203 * to clear the alpha. Then we add our alpha to it. 204 * We use 3 colors to get a step effect where it starts off very 205 * light and quickly becomes dark and then a slow transition to 206 * be even darker. 207 */ 208 color &= CLEAR_ALPHA_MASK; 209 int startColor = color | HIGH_ALPHA; 210 int middleColor = color | MED_ALPHA; 211 int endColor = color | LOW_ALPHA; 212 int[] colors = new int[] {startColor, middleColor, endColor}; 213 GradientDrawable d = new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT, colors); 214 d.setCornerRadii(CORNERS); 215 return d; 216 } 217 218 /** 219 * Formats the given Time object so that it gives the month and year 220 * (for example, "September 2007"). 221 * 222 * @param time the time to format 223 * @return the string containing the weekday and the date 224 */ 225 public static String formatMonthYear(Context context, Time time) { 226 return time.format(context.getResources().getString(R.string.month_year)); 227 } 228 229 /** 230 * Sets the time to the beginning of the day (midnight) by clearing the 231 * hour, minute, and second fields. 232 */ 233 static void setTimeToStartOfDay(Time time) { 234 time.second = 0; 235 time.minute = 0; 236 time.hour = 0; 237 } 238 239 /** 240 * Get first day of week as android.text.format.Time constant. 241 * @return the first day of week in android.text.format.Time 242 */ 243 public static int getFirstDayOfWeek() { 244 int startDay = Calendar.getInstance().getFirstDayOfWeek(); 245 if (startDay == Calendar.SATURDAY) { 246 return Time.SATURDAY; 247 } else if (startDay == Calendar.MONDAY) { 248 return Time.MONDAY; 249 } else { 250 return Time.SUNDAY; 251 } 252 } 253 254 /** 255 * Determine whether the column position is Saturday or not. 256 * @param column the column position 257 * @param firstDayOfWeek the first day of week in android.text.format.Time 258 * @return true if the column is Saturday position 259 */ 260 public static boolean isSaturday(int column, int firstDayOfWeek) { 261 return (firstDayOfWeek == Time.SUNDAY && column == 6) 262 || (firstDayOfWeek == Time.MONDAY && column == 5) 263 || (firstDayOfWeek == Time.SATURDAY && column == 0); 264 } 265 266 /** 267 * Determine whether the column position is Sunday or not. 268 * @param column the column position 269 * @param firstDayOfWeek the first day of week in android.text.format.Time 270 * @return true if the column is Sunday position 271 */ 272 public static boolean isSunday(int column, int firstDayOfWeek) { 273 return (firstDayOfWeek == Time.SUNDAY && column == 0) 274 || (firstDayOfWeek == Time.MONDAY && column == 6) 275 || (firstDayOfWeek == Time.SATURDAY && column == 1); 276 } 277 278 /** 279 * Scan through a cursor of calendars and check if names are duplicated. 280 * 281 * This travels a cursor containing calendar display names and fills in the provided map with 282 * whether or not each name is repeated. 283 * @param isDuplicateName The map to put the duplicate check results in. 284 * @param cursor The query of calendars to check 285 * @param nameIndex The column of the query that contains the display name 286 */ 287 public static void checkForDuplicateNames(Map<String, Boolean> isDuplicateName, Cursor cursor, 288 int nameIndex) { 289 isDuplicateName.clear(); 290 cursor.moveToPosition(-1); 291 while (cursor.moveToNext()) { 292 String displayName = cursor.getString(nameIndex); 293 // Set it to true if we've seen this name before, false otherwise 294 if (displayName != null) { 295 isDuplicateName.put(displayName, isDuplicateName.containsKey(displayName)); 296 } 297 } 298 } 299} 300