Home | History | Annotate | Download | only in deskclock
      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.deskclock;
     18 
     19 import android.app.Activity;
     20 import android.app.AlertDialog;
     21 import android.content.Context;
     22 import android.content.DialogInterface;
     23 import android.content.Intent;
     24 import android.content.SharedPreferences;
     25 import android.database.Cursor;
     26 import android.os.Bundle;
     27 import android.view.ContextMenu;
     28 import android.view.ContextMenu.ContextMenuInfo;
     29 import android.view.LayoutInflater;
     30 import android.view.Menu;
     31 import android.view.MenuItem;
     32 import android.view.View;
     33 import android.view.View.OnClickListener;
     34 import android.view.ViewGroup;
     35 import android.widget.AdapterView;
     36 import android.widget.AdapterView.AdapterContextMenuInfo;
     37 import android.widget.AdapterView.OnItemClickListener;
     38 import android.widget.CheckBox;
     39 import android.widget.CursorAdapter;
     40 import android.widget.ImageButton;
     41 import android.widget.ListView;
     42 import android.widget.TextView;
     43 
     44 import java.util.Calendar;
     45 
     46 /**
     47  * AlarmClock application.
     48  */
     49 public class AlarmClock extends Activity implements OnItemClickListener {
     50 
     51     static final String PREFERENCES = "AlarmClock";
     52 
     53     /** This must be false for production.  If true, turns on logging,
     54         test code, etc. */
     55     static final boolean DEBUG = false;
     56 
     57     private SharedPreferences mPrefs;
     58     private LayoutInflater mFactory;
     59     private ListView mAlarmsList;
     60     private Cursor mCursor;
     61 
     62     private void updateAlarm(boolean enabled,
     63             Alarm alarm) {
     64         Alarms.enableAlarm(this, alarm.id, enabled);
     65         if (enabled) {
     66             SetAlarm.popAlarmSetToast(this, alarm.hour, alarm.minutes,
     67                     alarm.daysOfWeek);
     68         }
     69     }
     70 
     71     private class AlarmTimeAdapter extends CursorAdapter {
     72         public AlarmTimeAdapter(Context context, Cursor cursor) {
     73             super(context, cursor);
     74         }
     75 
     76         @Override
     77         public View newView(Context context, Cursor cursor, ViewGroup parent) {
     78             View ret = mFactory.inflate(R.layout.alarm_time, parent, false);
     79 
     80             DigitalClock digitalClock =
     81                     (DigitalClock) ret.findViewById(R.id.digitalClock);
     82             digitalClock.setLive(false);
     83             return ret;
     84         }
     85 
     86         @Override
     87         public void bindView(View view, Context context, Cursor cursor) {
     88             final Alarm alarm = new Alarm(cursor);
     89 
     90             View indicator = view.findViewById(R.id.indicator);
     91 
     92             // Set the initial state of the clock "checkbox"
     93             final CheckBox clockOnOff =
     94                     (CheckBox) indicator.findViewById(R.id.clock_onoff);
     95             clockOnOff.setChecked(alarm.enabled);
     96 
     97             // Clicking outside the "checkbox" should also change the state.
     98             indicator.setOnClickListener(new OnClickListener() {
     99                 public void onClick(View v) {
    100                     clockOnOff.toggle();
    101                     updateAlarm(clockOnOff.isChecked(), alarm);
    102                 }
    103             });
    104 
    105             DigitalClock digitalClock =
    106                     (DigitalClock) view.findViewById(R.id.digitalClock);
    107 
    108             // set the alarm text
    109             final Calendar c = Calendar.getInstance();
    110             c.set(Calendar.HOUR_OF_DAY, alarm.hour);
    111             c.set(Calendar.MINUTE, alarm.minutes);
    112             digitalClock.updateTime(c);
    113 
    114             // Set the repeat text or leave it blank if it does not repeat.
    115             TextView daysOfWeekView =
    116                     (TextView) digitalClock.findViewById(R.id.daysOfWeek);
    117             final String daysOfWeekStr =
    118                     alarm.daysOfWeek.toString(AlarmClock.this, false);
    119             if (daysOfWeekStr != null && daysOfWeekStr.length() != 0) {
    120                 daysOfWeekView.setText(daysOfWeekStr);
    121                 daysOfWeekView.setVisibility(View.VISIBLE);
    122             } else {
    123                 daysOfWeekView.setVisibility(View.GONE);
    124             }
    125 
    126             // Display the label
    127             TextView labelView =
    128                     (TextView) view.findViewById(R.id.label);
    129             if (alarm.label != null && alarm.label.length() != 0) {
    130                 labelView.setText(alarm.label);
    131                 labelView.setVisibility(View.VISIBLE);
    132             } else {
    133                 labelView.setVisibility(View.GONE);
    134             }
    135         }
    136     };
    137 
    138     @Override
    139     public boolean onContextItemSelected(final MenuItem item) {
    140         final AdapterContextMenuInfo info =
    141                 (AdapterContextMenuInfo) item.getMenuInfo();
    142         final int id = (int) info.id;
    143         // Error check just in case.
    144         if (id == -1) {
    145             return super.onContextItemSelected(item);
    146         }
    147         switch (item.getItemId()) {
    148             case R.id.delete_alarm: {
    149                 // Confirm that the alarm will be deleted.
    150                 new AlertDialog.Builder(this)
    151                         .setTitle(getString(R.string.delete_alarm))
    152                         .setMessage(getString(R.string.delete_alarm_confirm))
    153                         .setPositiveButton(android.R.string.ok,
    154                                 new DialogInterface.OnClickListener() {
    155                                     public void onClick(DialogInterface d,
    156                                             int w) {
    157                                         Alarms.deleteAlarm(AlarmClock.this, id);
    158                                     }
    159                                 })
    160                         .setNegativeButton(android.R.string.cancel, null)
    161                         .show();
    162                 return true;
    163             }
    164 
    165             case R.id.enable_alarm: {
    166                 final Cursor c = (Cursor) mAlarmsList.getAdapter()
    167                         .getItem(info.position);
    168                 final Alarm alarm = new Alarm(c);
    169                 Alarms.enableAlarm(this, alarm.id, !alarm.enabled);
    170                 if (!alarm.enabled) {
    171                     SetAlarm.popAlarmSetToast(this, alarm.hour, alarm.minutes,
    172                             alarm.daysOfWeek);
    173                 }
    174                 return true;
    175             }
    176 
    177             case R.id.edit_alarm: {
    178                 final Cursor c = (Cursor) mAlarmsList.getAdapter()
    179                         .getItem(info.position);
    180                 final Alarm alarm = new Alarm(c);
    181                 Intent intent = new Intent(this, SetAlarm.class);
    182                 intent.putExtra(Alarms.ALARM_INTENT_EXTRA, alarm);
    183                 startActivity(intent);
    184                 return true;
    185             }
    186 
    187             default:
    188                 break;
    189         }
    190         return super.onContextItemSelected(item);
    191     }
    192 
    193     @Override
    194     protected void onCreate(Bundle icicle) {
    195         super.onCreate(icicle);
    196 
    197         mFactory = LayoutInflater.from(this);
    198         mPrefs = getSharedPreferences(PREFERENCES, 0);
    199         mCursor = Alarms.getAlarmsCursor(getContentResolver());
    200 
    201         updateLayout();
    202     }
    203 
    204     private void updateLayout() {
    205         setContentView(R.layout.alarm_clock);
    206         mAlarmsList = (ListView) findViewById(R.id.alarms_list);
    207         AlarmTimeAdapter adapter = new AlarmTimeAdapter(this, mCursor);
    208         mAlarmsList.setAdapter(adapter);
    209         mAlarmsList.setVerticalScrollBarEnabled(true);
    210         mAlarmsList.setOnItemClickListener(this);
    211         mAlarmsList.setOnCreateContextMenuListener(this);
    212 
    213         View addAlarm = findViewById(R.id.add_alarm);
    214         addAlarm.setOnClickListener(new View.OnClickListener() {
    215                 public void onClick(View v) {
    216                     addNewAlarm();
    217                 }
    218             });
    219         // Make the entire view selected when focused.
    220         addAlarm.setOnFocusChangeListener(new View.OnFocusChangeListener() {
    221                 public void onFocusChange(View v, boolean hasFocus) {
    222                     v.setSelected(hasFocus);
    223                 }
    224         });
    225         View doneButton = findViewById(R.id.done);
    226         if (doneButton != null) {
    227             doneButton.setOnClickListener(new View.OnClickListener() {
    228                 public void onClick(View v) {
    229                     finish();
    230                 }
    231             });
    232         }
    233     }
    234 
    235     private void addNewAlarm() {
    236         startActivity(new Intent(this, SetAlarm.class));
    237     }
    238 
    239     @Override
    240     protected void onDestroy() {
    241         super.onDestroy();
    242         ToastMaster.cancelToast();
    243         if (mCursor != null) {
    244             mCursor.close();
    245         }
    246     }
    247 
    248     @Override
    249     public void onCreateContextMenu(ContextMenu menu, View view,
    250             ContextMenuInfo menuInfo) {
    251         // Inflate the menu from xml.
    252         getMenuInflater().inflate(R.menu.context_menu, menu);
    253 
    254         // Use the current item to create a custom view for the header.
    255         final AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
    256         final Cursor c =
    257                 (Cursor) mAlarmsList.getAdapter().getItem(info.position);
    258         final Alarm alarm = new Alarm(c);
    259 
    260         // Construct the Calendar to compute the time.
    261         final Calendar cal = Calendar.getInstance();
    262         cal.set(Calendar.HOUR_OF_DAY, alarm.hour);
    263         cal.set(Calendar.MINUTE, alarm.minutes);
    264         final String time = Alarms.formatTime(this, cal);
    265 
    266         // Inflate the custom view and set each TextView's text.
    267         final View v = mFactory.inflate(R.layout.context_menu_header, null);
    268         TextView textView = (TextView) v.findViewById(R.id.header_time);
    269         textView.setText(time);
    270         textView = (TextView) v.findViewById(R.id.header_label);
    271         textView.setText(alarm.label);
    272 
    273         // Set the custom view on the menu.
    274         menu.setHeaderView(v);
    275         // Change the text based on the state of the alarm.
    276         if (alarm.enabled) {
    277             menu.findItem(R.id.enable_alarm).setTitle(R.string.disable_alarm);
    278         }
    279     }
    280 
    281     @Override
    282     public boolean onOptionsItemSelected(MenuItem item) {
    283         switch (item.getItemId()) {
    284             case R.id.menu_item_settings:
    285                 startActivity(new Intent(this, SettingsActivity.class));
    286                 return true;
    287             case R.id.menu_item_desk_clock:
    288                 startActivity(new Intent(this, DeskClock.class));
    289                 finish();
    290                 return true;
    291             case R.id.menu_item_add_alarm:
    292                 addNewAlarm();
    293                 return true;
    294             case R.id.menu_item_done:
    295                 finish();
    296                 return true;
    297             default:
    298                 break;
    299         }
    300         return super.onOptionsItemSelected(item);
    301     }
    302 
    303     @Override
    304     public boolean onCreateOptionsMenu(Menu menu) {
    305         getMenuInflater().inflate(R.menu.alarm_list_menu, menu);
    306         return super.onCreateOptionsMenu(menu);
    307     }
    308 
    309     @Override
    310     public void onItemClick(AdapterView parent, View v, int pos, long id) {
    311         final Cursor c = (Cursor) mAlarmsList.getAdapter()
    312                 .getItem(pos);
    313         final Alarm alarm = new Alarm(c);
    314         Intent intent = new Intent(this, SetAlarm.class);
    315         intent.putExtra(Alarms.ALARM_INTENT_EXTRA, alarm);
    316         startActivity(intent);
    317     }
    318 }
    319