Home | History | Annotate | Download | only in calendar
      1 /*
      2  * Copyright (C) 2007 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 
     17 package com.android.calendar;
     18 
     19 import android.app.Activity;
     20 import android.app.backup.BackupManager;
     21 import android.content.Context;
     22 import android.content.Intent;
     23 import android.content.SharedPreferences;
     24 import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
     25 import android.os.Bundle;
     26 import android.os.Vibrator;
     27 import android.preference.CheckBoxPreference;
     28 import android.preference.ListPreference;
     29 import android.preference.Preference;
     30 import android.preference.Preference.OnPreferenceChangeListener;
     31 import android.preference.PreferenceCategory;
     32 import android.preference.PreferenceFragment;
     33 import android.preference.PreferenceManager;
     34 import android.preference.PreferenceScreen;
     35 import android.preference.RingtonePreference;
     36 import android.provider.CalendarContract;
     37 import android.provider.CalendarContract.CalendarCache;
     38 import android.provider.SearchRecentSuggestions;
     39 import android.text.TextUtils;
     40 import android.widget.Toast;
     41 
     42 import com.android.calendar.alerts.AlertReceiver;
     43 
     44 public class GeneralPreferences extends PreferenceFragment implements
     45         OnSharedPreferenceChangeListener, OnPreferenceChangeListener {
     46     // The name of the shared preferences file. This name must be maintained for historical
     47     // reasons, as it's what PreferenceManager assigned the first time the file was created.
     48     static final String SHARED_PREFS_NAME = "com.android.calendar_preferences";
     49 
     50     // Preference keys
     51     public static final String KEY_HIDE_DECLINED = "preferences_hide_declined";
     52     public static final String KEY_WEEK_START_DAY = "preferences_week_start_day";
     53     public static final String KEY_SHOW_WEEK_NUM = "preferences_show_week_num";
     54     public static final String KEY_DAYS_PER_WEEK = "preferences_days_per_week";
     55     public static final String KEY_SKIP_SETUP = "preferences_skip_setup";
     56 
     57     public static final String KEY_CLEAR_SEARCH_HISTORY = "preferences_clear_search_history";
     58 
     59     public static final String KEY_ALERTS_CATEGORY = "preferences_alerts_category";
     60     public static final String KEY_ALERTS = "preferences_alerts";
     61     public static final String KEY_ALERTS_VIBRATE = "preferences_alerts_vibrate";
     62     public static final String KEY_ALERTS_VIBRATE_WHEN = "preferences_alerts_vibrateWhen";
     63     public static final String KEY_ALERTS_RINGTONE = "preferences_alerts_ringtone";
     64     public static final String KEY_ALERTS_POPUP = "preferences_alerts_popup";
     65 
     66     public static final String KEY_SHOW_CONTROLS = "preferences_show_controls";
     67 
     68     public static final String KEY_DEFAULT_REMINDER = "preferences_default_reminder";
     69     public static final int NO_REMINDER = -1;
     70     public static final String NO_REMINDER_STRING = "-1";
     71     public static final int REMINDER_DEFAULT_TIME = 10; // in minutes
     72 
     73     public static final String KEY_DEFAULT_CELL_HEIGHT = "preferences_default_cell_height";
     74     public static final String KEY_VERSION = "preferences_version";
     75 
     76     /** Key to SharePreference for default view (CalendarController.ViewType) */
     77     public static final String KEY_START_VIEW = "preferred_startView";
     78     /**
     79      *  Key to SharePreference for default detail view (CalendarController.ViewType)
     80      *  Typically used by widget
     81      */
     82     public static final String KEY_DETAILED_VIEW = "preferred_detailedView";
     83     public static final String KEY_DEFAULT_CALENDAR = "preference_defaultCalendar";
     84 
     85     // These must be in sync with the array preferences_week_start_day_values
     86     public static final String WEEK_START_DEFAULT = "-1";
     87     public static final String WEEK_START_SATURDAY = "7";
     88     public static final String WEEK_START_SUNDAY = "1";
     89     public static final String WEEK_START_MONDAY = "2";
     90 
     91     // These keys are kept to enable migrating users from previous versions
     92     private static final String KEY_ALERTS_TYPE = "preferences_alerts_type";
     93     private static final String ALERT_TYPE_ALERTS = "0";
     94     private static final String ALERT_TYPE_STATUS_BAR = "1";
     95     private static final String ALERT_TYPE_OFF = "2";
     96     static final String KEY_HOME_TZ_ENABLED = "preferences_home_tz_enabled";
     97     static final String KEY_HOME_TZ = "preferences_home_tz";
     98 
     99     // Default preference values
    100     public static final int DEFAULT_START_VIEW = CalendarController.ViewType.WEEK;
    101     public static final int DEFAULT_DETAILED_VIEW = CalendarController.ViewType.DAY;
    102     public static final boolean DEFAULT_SHOW_WEEK_NUM = false;
    103 
    104     CheckBoxPreference mAlert;
    105     ListPreference mVibrateWhen;
    106     RingtonePreference mRingtone;
    107     CheckBoxPreference mPopup;
    108     CheckBoxPreference mUseHomeTZ;
    109     CheckBoxPreference mHideDeclined;
    110     ListPreference mHomeTZ;
    111     ListPreference mWeekStart;
    112     ListPreference mDefaultReminder;
    113 
    114     private static CharSequence[][] mTimezones;
    115 
    116     /** Return a properly configured SharedPreferences instance */
    117     public static SharedPreferences getSharedPreferences(Context context) {
    118         return context.getSharedPreferences(SHARED_PREFS_NAME, Context.MODE_PRIVATE);
    119     }
    120 
    121     /** Set the default shared preferences in the proper context */
    122     public static void setDefaultValues(Context context) {
    123         PreferenceManager.setDefaultValues(context, SHARED_PREFS_NAME, Context.MODE_PRIVATE,
    124                 R.xml.general_preferences, false);
    125     }
    126 
    127     @Override
    128     public void onCreate(Bundle icicle) {
    129         super.onCreate(icicle);
    130 
    131         final Activity activity = getActivity();
    132 
    133         // Make sure to always use the same preferences file regardless of the package name
    134         // we're running under
    135         final PreferenceManager preferenceManager = getPreferenceManager();
    136         final SharedPreferences sharedPreferences = getSharedPreferences(activity);
    137         preferenceManager.setSharedPreferencesName(SHARED_PREFS_NAME);
    138 
    139         // Load the preferences from an XML resource
    140         addPreferencesFromResource(R.xml.general_preferences);
    141 
    142         final PreferenceScreen preferenceScreen = getPreferenceScreen();
    143         mAlert = (CheckBoxPreference) preferenceScreen.findPreference(KEY_ALERTS);
    144         mVibrateWhen = (ListPreference) preferenceScreen.findPreference(KEY_ALERTS_VIBRATE_WHEN);
    145         Vibrator vibrator = (Vibrator) activity.getSystemService(Context.VIBRATOR_SERVICE);
    146         if (vibrator == null || !vibrator.hasVibrator()) {
    147             PreferenceCategory mAlertGroup = (PreferenceCategory) preferenceScreen
    148                     .findPreference(KEY_ALERTS_CATEGORY);
    149             mAlertGroup.removePreference(mVibrateWhen);
    150         } else {
    151             mVibrateWhen.setSummary(mVibrateWhen.getEntry());
    152         }
    153 
    154         mRingtone = (RingtonePreference) preferenceScreen.findPreference(KEY_ALERTS_RINGTONE);
    155         mPopup = (CheckBoxPreference) preferenceScreen.findPreference(KEY_ALERTS_POPUP);
    156         mUseHomeTZ = (CheckBoxPreference) preferenceScreen.findPreference(KEY_HOME_TZ_ENABLED);
    157         mHideDeclined = (CheckBoxPreference) preferenceScreen.findPreference(KEY_HIDE_DECLINED);
    158         mWeekStart = (ListPreference) preferenceScreen.findPreference(KEY_WEEK_START_DAY);
    159         mDefaultReminder = (ListPreference) preferenceScreen.findPreference(KEY_DEFAULT_REMINDER);
    160         mHomeTZ = (ListPreference) preferenceScreen.findPreference(KEY_HOME_TZ);
    161         String tz = mHomeTZ.getValue();
    162 
    163         mWeekStart.setSummary(mWeekStart.getEntry());
    164         mDefaultReminder.setSummary(mDefaultReminder.getEntry());
    165 
    166         if (mTimezones == null) {
    167             mTimezones = (new TimezoneAdapter(activity, tz, System.currentTimeMillis()))
    168                     .getAllTimezones();
    169         }
    170         mHomeTZ.setEntryValues(mTimezones[0]);
    171         mHomeTZ.setEntries(mTimezones[1]);
    172         CharSequence tzName = mHomeTZ.getEntry();
    173         if (TextUtils.isEmpty(tzName)) {
    174             tzName = Utils.getTimeZone(activity, null);
    175         }
    176         mHomeTZ.setSummary(tzName);
    177 
    178         migrateOldPreferences(sharedPreferences);
    179 
    180         updateChildPreferences();
    181     }
    182 
    183     @Override
    184     public void onResume() {
    185         super.onResume();
    186         getPreferenceScreen().getSharedPreferences()
    187                 .registerOnSharedPreferenceChangeListener(this);
    188         setPreferenceListeners(this);
    189     }
    190 
    191     /**
    192      * Sets up all the preference change listeners to use the specified
    193      * listener.
    194      */
    195     private void setPreferenceListeners(OnPreferenceChangeListener listener) {
    196         mUseHomeTZ.setOnPreferenceChangeListener(listener);
    197         mHomeTZ.setOnPreferenceChangeListener(listener);
    198         mWeekStart.setOnPreferenceChangeListener(listener);
    199         mDefaultReminder.setOnPreferenceChangeListener(listener);
    200         mRingtone.setOnPreferenceChangeListener(listener);
    201         mHideDeclined.setOnPreferenceChangeListener(listener);
    202         mVibrateWhen.setOnPreferenceChangeListener(listener);
    203 
    204     }
    205 
    206     @Override
    207     public void onPause() {
    208         super.onPause();
    209         getPreferenceScreen().getSharedPreferences()
    210                 .unregisterOnSharedPreferenceChangeListener(this);
    211         setPreferenceListeners(null);
    212     }
    213 
    214     @Override
    215     public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
    216         Activity a = getActivity();
    217         if (key.equals(KEY_ALERTS)) {
    218             updateChildPreferences();
    219             if (a != null) {
    220                 Intent intent = new Intent();
    221                 intent.setClass(a, AlertReceiver.class);
    222                 if (mAlert.isChecked()) {
    223                     intent.setAction(AlertReceiver.ACTION_DISMISS_OLD_REMINDERS);
    224                 } else {
    225                     intent.setAction(CalendarContract.ACTION_EVENT_REMINDER);
    226                 }
    227                 a.sendBroadcast(intent);
    228             }
    229         }
    230         if (a != null) {
    231             BackupManager.dataChanged(a.getPackageName());
    232         }
    233     }
    234 
    235     /**
    236      * Handles time zone preference changes
    237      */
    238     @Override
    239     public boolean onPreferenceChange(Preference preference, Object newValue) {
    240         String tz;
    241         if (preference == mUseHomeTZ) {
    242             if ((Boolean)newValue) {
    243                 tz = mHomeTZ.getValue();
    244             } else {
    245                 tz = CalendarCache.TIMEZONE_TYPE_AUTO;
    246             }
    247             Utils.setTimeZone(getActivity(), tz);
    248             return true;
    249         } else if (preference == mHideDeclined) {
    250             mHideDeclined.setChecked((Boolean) newValue);
    251             Activity act = getActivity();
    252             Intent intent = new Intent(Utils.getWidgetScheduledUpdateAction(act));
    253             intent.setDataAndType(CalendarContract.CONTENT_URI, Utils.APPWIDGET_DATA_TYPE);
    254             act.sendBroadcast(intent);
    255             return true;
    256         } else if (preference == mHomeTZ) {
    257             tz = (String) newValue;
    258             // We set the value here so we can read back the entry
    259             mHomeTZ.setValue(tz);
    260             mHomeTZ.setSummary(mHomeTZ.getEntry());
    261             Utils.setTimeZone(getActivity(), tz);
    262         } else if (preference == mWeekStart) {
    263             mWeekStart.setValue((String) newValue);
    264             mWeekStart.setSummary(mWeekStart.getEntry());
    265         } else if (preference == mDefaultReminder) {
    266             mDefaultReminder.setValue((String) newValue);
    267             mDefaultReminder.setSummary(mDefaultReminder.getEntry());
    268         } else if (preference == mRingtone) {
    269             // TODO update this after b/3417832 is fixed
    270             return true;
    271         } else if (preference == mVibrateWhen) {
    272             mVibrateWhen.setValue((String)newValue);
    273             mVibrateWhen.setSummary(mVibrateWhen.getEntry());
    274         } else {
    275             return true;
    276         }
    277         return false;
    278     }
    279 
    280     /**
    281      * If necessary, upgrades previous versions of preferences to the current
    282      * set of keys and values.
    283      * @param prefs the preferences to upgrade
    284      */
    285     private void migrateOldPreferences(SharedPreferences prefs) {
    286         // If needed, migrate vibration setting from a previous version
    287         if (!prefs.contains(KEY_ALERTS_VIBRATE_WHEN) &&
    288                 prefs.contains(KEY_ALERTS_VIBRATE)) {
    289             int stringId = prefs.getBoolean(KEY_ALERTS_VIBRATE, false) ?
    290                     R.string.prefDefault_alerts_vibrate_true :
    291                     R.string.prefDefault_alerts_vibrate_false;
    292             mVibrateWhen.setValue(getActivity().getString(stringId));
    293         }
    294         // If needed, migrate the old alerts type settin
    295         if (!prefs.contains(KEY_ALERTS) && prefs.contains(KEY_ALERTS_TYPE)) {
    296             String type = prefs.getString(KEY_ALERTS_TYPE, ALERT_TYPE_STATUS_BAR);
    297             if (type.equals(ALERT_TYPE_OFF)) {
    298                 mAlert.setChecked(false);
    299                 mPopup.setChecked(false);
    300                 mPopup.setEnabled(false);
    301             } else if (type.equals(ALERT_TYPE_STATUS_BAR)) {
    302                 mAlert.setChecked(true);
    303                 mPopup.setChecked(false);
    304                 mPopup.setEnabled(true);
    305             } else if (type.equals(ALERT_TYPE_ALERTS)) {
    306                 mAlert.setChecked(true);
    307                 mPopup.setChecked(true);
    308                 mPopup.setEnabled(true);
    309             }
    310             // clear out the old setting
    311             prefs.edit().remove(KEY_ALERTS_TYPE).commit();
    312         }
    313     }
    314 
    315     /**
    316      * Keeps the dependent settings in sync with the parent preference, so for
    317      * example, when notifications are turned off, we disable the preferences
    318      * for configuring the exact notification behavior.
    319      */
    320     private void updateChildPreferences() {
    321         if (mAlert.isChecked()) {
    322             mVibrateWhen.setEnabled(true);
    323             mRingtone.setEnabled(true);
    324             mPopup.setEnabled(true);
    325         } else {
    326             mVibrateWhen.setValue(
    327                     getActivity().getString(R.string.prefDefault_alerts_vibrate_false));
    328             mVibrateWhen.setEnabled(false);
    329             mRingtone.setEnabled(false);
    330             mPopup.setEnabled(false);
    331         }
    332     }
    333 
    334 
    335     @Override
    336     public boolean onPreferenceTreeClick(
    337             PreferenceScreen preferenceScreen, Preference preference) {
    338         final String key = preference.getKey();
    339         if (KEY_CLEAR_SEARCH_HISTORY.equals(key)) {
    340             SearchRecentSuggestions suggestions = new SearchRecentSuggestions(getActivity(),
    341                     Utils.getSearchAuthority(getActivity()),
    342                     CalendarRecentSuggestionsProvider.MODE);
    343             suggestions.clearHistory();
    344             Toast.makeText(getActivity(), R.string.search_history_cleared,
    345                     Toast.LENGTH_SHORT).show();
    346             return true;
    347         } else {
    348             return super.onPreferenceTreeClick(preferenceScreen, preference);
    349         }
    350     }
    351 
    352 }
    353