OSDN Git Service

Automated import from //branches/donutburger/...@140507,140507
[android-x86/packages-apps-DeskClock.git] / src / com / android / alarmclock / AlarmClock.java
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.alarmclock;
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.net.Uri;
27 import android.os.Bundle;
28 import android.os.Handler;
29 import android.provider.Settings;
30 import android.view.ContextMenu;
31 import android.view.ContextMenu.ContextMenuInfo;
32 import android.view.LayoutInflater;
33 import android.view.Menu;
34 import android.view.MenuItem;
35 import android.view.View;
36 import android.view.View.OnClickListener;
37 import android.view.ViewGroup;
38 import android.widget.CursorAdapter;
39 import android.widget.ListView;
40 import android.widget.TextView;
41 import android.widget.CheckBox;
42
43 import java.util.Calendar;
44
45 /**
46  * AlarmClock application.
47  */
48 public class AlarmClock extends Activity {
49
50     final static String PREFERENCES = "AlarmClock";
51     final static int SET_ALARM = 1;
52     final static String PREF_CLOCK_FACE = "face";
53     final static String PREF_SHOW_CLOCK = "show_clock";
54
55     /** Cap alarm count at this number */
56     final static int MAX_ALARM_COUNT = 12;
57
58     /** This must be false for production.  If true, turns on logging,
59         test code, etc. */
60     final static boolean DEBUG = false;
61
62     private SharedPreferences mPrefs;
63     private LayoutInflater mFactory;
64     private ViewGroup mClockLayout;
65     private View mClock = null;
66     private MenuItem mAddAlarmItem;
67     private MenuItem mToggleClockItem;
68     private ListView mAlarmsList;
69     private Cursor mCursor;
70
71     /**
72      * Which clock face to show
73      */
74     private int mFace = -1;
75
76     /*
77      * FIXME: it would be nice for this to live in an xml config file.
78      */
79     final static int[] CLOCKS = {
80         R.layout.clock_basic_bw,
81         R.layout.clock_googly,
82         R.layout.clock_droid2,
83         R.layout.clock_droids,
84         R.layout.digital_clock
85     };
86
87     private class AlarmTimeAdapter extends CursorAdapter {
88         public AlarmTimeAdapter(Context context, Cursor cursor) {
89             super(context, cursor);
90         }
91
92         public View newView(Context context, Cursor cursor, ViewGroup parent) {
93             View ret = mFactory.inflate(R.layout.alarm_time, parent, false);
94             DigitalClock digitalClock = (DigitalClock)ret.findViewById(R.id.digitalClock);
95             digitalClock.setLive(false);
96             if (Log.LOGV) Log.v("newView " + cursor.getPosition());
97             return ret;
98         }
99
100         public void bindView(View view, Context context, Cursor cursor) {
101             final int id = cursor.getInt(Alarms.AlarmColumns.ALARM_ID_INDEX);
102             final int hour = cursor.getInt(Alarms.AlarmColumns.ALARM_HOUR_INDEX);
103             final int minutes = cursor.getInt(Alarms.AlarmColumns.ALARM_MINUTES_INDEX);
104             final Alarms.DaysOfWeek daysOfWeek = new Alarms.DaysOfWeek(
105                     cursor.getInt(Alarms.AlarmColumns.ALARM_DAYS_OF_WEEK_INDEX));
106             final boolean enabled = cursor.getInt(Alarms.AlarmColumns.ALARM_ENABLED_INDEX) == 1;
107             final String label =
108                     cursor.getString(Alarms.AlarmColumns.ALARM_MESSAGE_INDEX);
109
110             CheckBox onButton = (CheckBox)view.findViewById(R.id.alarmButton);
111             onButton.setChecked(enabled);
112             onButton.setOnClickListener(new OnClickListener() {
113                     public void onClick(View v) {
114                         boolean isChecked = ((CheckBox) v).isChecked();
115                         Alarms.enableAlarm(AlarmClock.this, id, isChecked);
116                         if (isChecked) {
117                             SetAlarm.popAlarmSetToast(
118                                     AlarmClock.this, hour, minutes, daysOfWeek);
119                         }
120                     }
121             });
122
123             DigitalClock digitalClock = (DigitalClock)view.findViewById(R.id.digitalClock);
124             if (Log.LOGV) Log.v("bindView " + cursor.getPosition() + " " + id + " " + hour +
125                                 ":" + minutes + " " + daysOfWeek.toString(context, true) + " dc " + digitalClock);
126
127             digitalClock.setOnClickListener(new OnClickListener() {
128                     public void onClick(View v) {
129                         if (true) {
130                             Intent intent = new Intent(AlarmClock.this, SetAlarm.class);
131                             intent.putExtra(Alarms.ID, id);
132                             startActivityForResult(intent, SET_ALARM);
133                         } else {
134                             // TESTING: immediately pop alarm
135                             Intent fireAlarm = new Intent(AlarmClock.this, AlarmAlert.class);
136                             fireAlarm.putExtra(Alarms.ID, id);
137                             fireAlarm.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
138                             startActivity(fireAlarm);
139                         }
140                     }
141                 });
142
143             // set the alarm text
144             final Calendar c = Calendar.getInstance();
145             c.set(Calendar.HOUR_OF_DAY, hour);
146             c.set(Calendar.MINUTE, minutes);
147             digitalClock.updateTime(c);
148
149             // Set the repeat text or leave it blank if it does not repeat.
150             TextView daysOfWeekView = (TextView) digitalClock.findViewById(R.id.daysOfWeek);
151             final String daysOfWeekStr =
152                     daysOfWeek.toString(AlarmClock.this, false);
153             if (daysOfWeekStr != null && daysOfWeekStr.length() != 0) {
154                 daysOfWeekView.setText(daysOfWeekStr);
155                 daysOfWeekView.setVisibility(View.VISIBLE);
156             } else {
157                 daysOfWeekView.setVisibility(View.GONE);
158             }
159
160             // Display the label
161             TextView labelView =
162                     (TextView) digitalClock.findViewById(R.id.label);
163             if (label != null && label.length() != 0) {
164                 labelView.setText(label);
165             } else {
166                 labelView.setText(R.string.default_label);
167             }
168
169             // Build context menu
170             digitalClock.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {
171                     public void onCreateContextMenu(ContextMenu menu, View view,
172                                                     ContextMenuInfo menuInfo) {
173                         menu.setHeaderTitle(Alarms.formatTime(AlarmClock.this, c));
174                         MenuItem deleteAlarmItem = menu.add(0, id, 0, R.string.delete_alarm);
175                     }
176                 });
177         }
178     };
179
180     @Override
181     public boolean onContextItemSelected(final MenuItem item) {
182         // Confirm that the alarm will be deleted.
183         new AlertDialog.Builder(this)
184                 .setTitle(getString(R.string.delete_alarm))
185                 .setMessage(getString(R.string.delete_alarm_confirm))
186                 .setPositiveButton(android.R.string.ok,
187                         new DialogInterface.OnClickListener() {
188                             public void onClick(DialogInterface d, int w) {
189                                 Alarms.deleteAlarm(AlarmClock.this,
190                                         item.getItemId());
191                             }
192                         })
193                 .setNegativeButton(android.R.string.cancel, null)
194                 .show();
195         return true;
196     }
197
198     @Override
199     protected void onCreate(Bundle icicle) {
200         super.onCreate(icicle);
201
202         // sanity check -- no database, no clock
203         if (getContentResolver() == null) {
204             new AlertDialog.Builder(this)
205                     .setTitle(getString(R.string.error))
206                     .setMessage(getString(R.string.dberror))
207                     .setPositiveButton(
208                             android.R.string.ok,
209                             new DialogInterface.OnClickListener() {
210                                 public void onClick(DialogInterface dialog, int which) {
211                                     finish();
212                                 }
213                             })
214                     .setOnCancelListener(
215                             new DialogInterface.OnCancelListener() {
216                                 public void onCancel(DialogInterface dialog) {
217                                     finish();
218                                 }})
219                     .setIcon(android.R.drawable.ic_dialog_alert)
220                     .create().show();
221             return;
222         }
223
224         setContentView(R.layout.alarm_clock);
225         mFactory = LayoutInflater.from(this);
226         mPrefs = getSharedPreferences(PREFERENCES, 0);
227
228         mCursor = Alarms.getAlarmsCursor(getContentResolver());
229         mAlarmsList = (ListView) findViewById(R.id.alarms_list);
230         mAlarmsList.setAdapter(new AlarmTimeAdapter(this, mCursor));
231         mAlarmsList.setVerticalScrollBarEnabled(true);
232         mAlarmsList.setItemsCanFocus(true);
233
234         mClockLayout = (ViewGroup) findViewById(R.id.clock_layout);
235         mClockLayout.setOnClickListener(new View.OnClickListener() {
236                 public void onClick(View v) {
237                     final Intent intent = new Intent(AlarmClock.this, ClockPicker.class);
238                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
239                     startActivity(intent);
240                 }
241             });
242
243         setClockVisibility(mPrefs.getBoolean(PREF_SHOW_CLOCK, true));
244     }
245
246     @Override
247     protected void onResume() {
248         super.onResume();
249
250         int face = mPrefs.getInt(PREF_CLOCK_FACE, 0);
251         if (mFace != face) {
252             if (face < 0 || face >= AlarmClock.CLOCKS.length)
253                 mFace = 0;
254             else
255                 mFace = face;
256             inflateClock();
257         }
258     }
259
260     @Override
261     protected void onDestroy() {
262         super.onDestroy();
263         ToastMaster.cancelToast();
264         mCursor.deactivate();
265     }
266
267     protected void inflateClock() {
268         if (mClock != null) {
269             mClockLayout.removeView(mClock);
270         }
271         mClock = mFactory.inflate(CLOCKS[mFace], null);
272         mClockLayout.addView(mClock, 0);
273     }
274
275     @Override
276     public boolean onCreateOptionsMenu(Menu menu) {
277         super.onCreateOptionsMenu(menu);
278
279         mAddAlarmItem = menu.add(0, 0, 0, R.string.add_alarm);
280         mAddAlarmItem.setIcon(android.R.drawable.ic_menu_add);
281
282         mToggleClockItem = menu.add(0, 0, 0, R.string.hide_clock);
283         mToggleClockItem.setIcon(R.drawable.ic_menu_clock_face);
284         
285         MenuItem settingsItem = menu.add(0, 0, 0, R.string.settings);
286         settingsItem.setIcon(android.R.drawable.ic_menu_preferences);
287         settingsItem.setIntent(new Intent(this, SettingsActivity.class));
288
289         return true;
290     }
291
292     /**
293      * Only allow user to add a new alarm if there are fewer than
294      * MAX_ALARM_COUNT
295      */
296     @Override
297     public boolean onPrepareOptionsMenu(Menu menu) {
298         super.onPrepareOptionsMenu(menu);
299         mAddAlarmItem.setVisible(mAlarmsList.getChildCount() < MAX_ALARM_COUNT);
300         mToggleClockItem.setTitle(getClockVisibility() ? R.string.hide_clock :
301                                   R.string.show_clock);
302         return true;
303     }
304
305     @Override
306     public boolean onOptionsItemSelected(MenuItem item) {
307         if (item == mAddAlarmItem) {
308             Uri uri = Alarms.addAlarm(getContentResolver());
309             // FIXME: scroll to new item.  mAlarmsList.requestChildRectangleOnScreen() ?
310             String segment = uri.getPathSegments().get(1);
311             int newId = Integer.parseInt(segment);
312             if (Log.LOGV) Log.v("In AlarmClock, new alarm id = " + newId);
313             Intent intent = new Intent(AlarmClock.this, SetAlarm.class);
314             intent.putExtra(Alarms.ID, newId);
315             startActivityForResult(intent, SET_ALARM);
316             return true;
317         } else if (item == mToggleClockItem) {
318             setClockVisibility(!getClockVisibility());
319             saveClockVisibility();
320             return true;
321         }
322
323         return false;
324     }
325
326
327     private boolean getClockVisibility() {
328         return mClockLayout.getVisibility() == View.VISIBLE;
329     }
330
331     private void setClockVisibility(boolean visible) {
332         mClockLayout.setVisibility(visible ? View.VISIBLE : View.GONE);
333     }
334
335     private void saveClockVisibility() {
336         mPrefs.edit().putBoolean(PREF_SHOW_CLOCK, getClockVisibility()).commit();
337     }
338 }